在使用R中的条件删除两个数据帧中的重复行后,如何在两个数据帧中查找相互对

在使用R中的条件删除两个数据帧中的重复行后,如何在两个数据帧中查找相互对,r,dataframe,comparison,R,Dataframe,Comparison,我掌握的数据如下: RES1 <- c("A","B","A","A","B") RES2 <- c("B","A","A","B","A") VAL1 <-c(3,5,3,6,8) VAL2 <- c(5,3,7,2,7) dff <- data.frame(RES1,VAL1,RES2,VAL2) dff RES1 VAL1 RES2 VAL2 1 A 3 B 5 2 B 5 A 3 3 A

我掌握的数据如下:

RES1 <- c("A","B","A","A","B")
RES2 <- c("B","A","A","B","A")
VAL1 <-c(3,5,3,6,8)
VAL2 <- c(5,3,7,2,7)
dff <- data.frame(RES1,VAL1,RES2,VAL2)
dff
  RES1 VAL1 RES2 VAL2
  1    A    3    B    5 
  2    B    5    A    3
  3    A    3    A    7
  4    A    6    B    2
  5    B    8    A    7
然后我想对另一个数据帧执行相同的操作,例如:

RES3 <- c("B","B","B","A","B")
RES4 <- c("A","A","A","A","B")
VAL4 <- c(3,7,5,3,8)
VAL3 <- c(5,8,3,7,3)
df2 <- data.frame(RES3,VAL3,RES4,VAL4)

df2
  RES3 VAL3 RES4 VAL4
   1     B     5     A     3
   2     B     8     A     7
   3     B     3     A     5
   4     A     7     A     3
   5     B     3     B     8
按照我的逻辑,你可以试试这个

df2 <- structure(list(RES3 = c("B", "B", "B", "A", "B"), VAL3 = c(5, 8, 3, 7, 3), RES4 = c("A", "A", "A", "A", "B"), VAL4 = c(3, 7, 5, 3, 8)), .Names = c("RES3", "VAL3", "RES4", "VAL4"), row.names = c(NA, -5L), class = "data.frame")
dff <- structure(list(RES1 = c("A", "B", "A", "A", "B"), VAL1 = c(3, 5, 3, 6, 8), RES2 = c("B", "A", "A", "B", "A"), VAL2 = c(5, 3, 7, 2, 7)), .Names = c("RES1", "VAL1", "RES2", "VAL2"), row.names = c(NA, -5L), class = "data.frame")
在两个数据帧上使用它,并找到共同的数据帧;然后,您可以使用该索引1子集原始数据帧或2,因为它已经包含您想要的信息,只需撤消f所做的,例如

按照我的逻辑,你可以试试这个

df2 <- structure(list(RES3 = c("B", "B", "B", "A", "B"), VAL3 = c(5, 8, 3, 7, 3), RES4 = c("A", "A", "A", "A", "B"), VAL4 = c(3, 7, 5, 3, 8)), .Names = c("RES3", "VAL3", "RES4", "VAL4"), row.names = c(NA, -5L), class = "data.frame")
dff <- structure(list(RES1 = c("A", "B", "A", "A", "B"), VAL1 = c(3, 5, 3, 6, 8), RES2 = c("B", "A", "A", "B", "A"), VAL2 = c(5, 3, 7, 2, 7)), .Names = c("RES1", "VAL1", "RES2", "VAL2"), row.names = c(NA, -5L), class = "data.frame")
在两个数据帧上使用它,并找到共同的数据帧;然后,您可以使用该索引1子集原始数据帧或2,因为它已经包含您想要的信息,只需撤消f所做的,例如

这里有一个解决方案:

library(dplyr)
df1$combined <- apply(df1, 1, function(x) paste(sort(c(paste(x[1], x[2], collapse = ','), paste(x[3], x[4], collapse = ','))), collapse = ','))
df2$combined <- apply(df2, 1, function(x) paste(sort(c(paste(x[1], x[2], collapse = ','), paste(x[3], x[4], collapse = ','))), collapse = ','))

df <- inner_join(df1 %>% group_by(combined) %>% slice(1), df2 %>% group_by(combined) %>% slice(1))
df <- df %>% ungroup() %>% select(RES1, VAL1, RES2, VAL2)
这种方法只需一次通过上述应用函数中的数据,并依赖于高效的dplyr group_by和INTERNAR_join

主要任务是以一定的顺序获取列对,以便按此顺序对它们进行分组。前两行只是将两对列“追加”到一个字符串中,该字符串按顺序排列,使每对中出现的值计数相同。然后,group_by使用相同的组合列对所有行进行分组,并使用slice获取第一行。使用内部_join连接生成的两个数据帧可确保仅保留两个数据帧之间公用的行。最后一行只是选择要保留的所需列。顺便说一句,对于上面的消息,如果您只想通过组合列而不想通过其他方式进行连接,则可能需要在内部连接调用中通过参数指定。

这里有一个解决方案:

library(dplyr)
df1$combined <- apply(df1, 1, function(x) paste(sort(c(paste(x[1], x[2], collapse = ','), paste(x[3], x[4], collapse = ','))), collapse = ','))
df2$combined <- apply(df2, 1, function(x) paste(sort(c(paste(x[1], x[2], collapse = ','), paste(x[3], x[4], collapse = ','))), collapse = ','))

df <- inner_join(df1 %>% group_by(combined) %>% slice(1), df2 %>% group_by(combined) %>% slice(1))
df <- df %>% ungroup() %>% select(RES1, VAL1, RES2, VAL2)
这种方法只需一次通过上述应用函数中的数据,并依赖于高效的dplyr group_by和INTERNAR_join


主要任务是以一定的顺序获取列对,以便按此顺序对它们进行分组。前两行只是将两对列“追加”到一个字符串中,该字符串按顺序排列,使每对中出现的值计数相同。然后,group_by使用相同的组合列对所有行进行分组,并使用slice获取第一行。使用内部_join连接生成的两个数据帧可确保仅保留两个数据帧之间公用的行。最后一行只是选择要保留的所需列。顺便说一句-对于上面的消息,如果只想通过组合列而不是其他方式进行连接,则可能需要在内部连接调用中通过参数指定。

如果数据帧中有更多列,该怎么办?@wthimdh您只有两对res/val吗?使用fdata[、c'res1'、'val1'、'res2'、'val2']或其他子集设置方法。f可以取任意数量的res/val对,但它确实假设使用的数据帧仅由res/valoh对组成,不幸的是,我还有其他列:s但我只需要使用两对res/val@rawr@wthimdh这就是为什么我建议使用fdata[,c'res1','val1','res2','val2',]或任意数量的res/val对。fdata[,grep'res | val',namesdata]任何子集设置方法都可以工作如果数据帧中有更多列怎么办?@wthimdh您只有两对res/val吗?使用fdata[、c'res1'、'val1'、'res2'、'val2']或其他子集设置方法。f可以取任意数量的res/val对,但它确实假设使用的数据帧仅由res/valoh对组成,不幸的是,我还有其他列:s但我只需要使用两对res/val@rawr@wthimdh这就是为什么我建议使用fdata[,c'res1','val1','res2','val2',]或任意数量的res/val对。fdata[,grep'res | val',namesdata]任何子集方法都有效。您的答案是否也假设数据帧没有任何其他列?因为我试过了,它在我的代码x[1],x[2]中的真实数据上给了我一个错误。根据您的输入,x[2]等假设了某些列的位置。您可能需要进行相应的调整。也许你可以发布你看到的错误?对不起,这是我的打字错误。它只是给出了一个类似加入的警告:cvalue、resi、AAi、chaini、secstri、resj、AAj、chainj、secstrj、numeraval、denomVal、combined,但它可以工作!谢谢。你能解释一下吗?是否创建了一个包含RES1 VAL1、RES2 VAL2的列,然后选择唯一和公共对?我添加到了答案中。希望有帮助。您可以执行每一行代码并查看发生了什么。包括内部连接调用中的各个部分。您是否介意给出一个示例,说明如何在一个数据帧中查找唯一的RES1 VAL1、RES2 VAL2pairs?不与另一个数据帧进行比较?以便我理解每一行,并在必要时进行修改。。感谢Adnvance您的回答是否也假设数据帧没有任何其他列?因为我试过了,它在我的代码x[1],x[2]中的真实数据上给了我一个错误。根据您的输入,x[2]等假设了某些列的位置。您可能需要进行相应的调整。也许你可以发布你看到的错误?对不起,这是我的打字错误。它只是给出了一个警告,比如加入:cvalue,
resi、AAi、chaini、secstri、resj、AAj、chainj、secstrj、NUMEVAL、denomVal组合在一起,但它可以工作!谢谢。你能解释一下吗?是否创建了一个包含RES1 VAL1、RES2 VAL2的列,然后选择唯一和公共对?我添加到了答案中。希望有帮助。您可以执行每一行代码并查看发生了什么。包括内部连接调用中的各个部分。您是否介意给出一个示例,说明如何在一个数据帧中查找唯一的RES1 VAL1、RES2 VAL2pairs?不与另一个数据帧进行比较?以便我理解每一行,并在必要时进行修改。。非常感谢
f(dff)
# [1] "A 3 B 5" "A 3 B 5" "A 3 A 7" "A 6 B 2" "A 7 B 8"
dff$idx <- f(dff)
df2$idx <- f(df2)

idx <- intersect(dff$idx, df2$idx)

read.table(text = idx, col.names = c('RESA','VALA','RESB','VALB'))
#   RESA VALA RESB VALB
# 1    A    3    B    5
# 2    A    3    A    7
# 3    A    7    B    8
library(dplyr)
df1$combined <- apply(df1, 1, function(x) paste(sort(c(paste(x[1], x[2], collapse = ','), paste(x[3], x[4], collapse = ','))), collapse = ','))
df2$combined <- apply(df2, 1, function(x) paste(sort(c(paste(x[1], x[2], collapse = ','), paste(x[3], x[4], collapse = ','))), collapse = ','))

df <- inner_join(df1 %>% group_by(combined) %>% slice(1), df2 %>% group_by(combined) %>% slice(1))
df <- df %>% ungroup() %>% select(RES1, VAL1, RES2, VAL2)
Source: local data frame [3 x 4]

    RES1  VAL1   RES2  VAL2
  (fctr) (dbl) (fctr) (dbl)
1      A     3      A     7
2      A     3      B     5
3      B     8      A     7