我想检查df1中任何行的2列是否== df2中任何行的相同2列

时间:2020-06-27 11:09:59

标签: r for-loop

我有2个这样的dfs

df1 <- data.frame("A" = c(1,2,3,4,5), "B" = c(10,20,30,40,50), "C" = c(6,7,8,9,11))
df2 <- data.frame("A" = c(10,4,30,20,50), "B" = c(1,40,3,7,5)), "C" = c(12,13,14,15))

我想查找df 1中是否有一行== df2中的A和B列。您可以看到df1[4,1:2] == df2[2,1:2]

我尝试过

for (i in 1:5){
  if (for (j in 1:5){
    df[i,1:2] == df2[j,1:2]})
    print("true")
}

但是它给了我这个错误:Error in if (for (j in 1:5) { : argument is of length zero

4 个答案:

答案 0 :(得分:2)

您可以行绑定列A和B,并使用anyDuplicated()

anyDuplicated(rbind(df1[1:2], df2[1:2])) > 0
[1] TRUE

如果数据框中可能存在重复项,则需要首先使其唯一:

anyDuplicated(rbind(unique(df1[1:2]), unique(df2[1:2]))) > 0

答案 1 :(得分:2)

您可以按行paste的值并使用%in%检查重复项:

df1[do.call(paste, df1[1:2]) %in% do.call(paste, df2[1:2]),]
#  A  B C
#4 4 40 9

如果您只需要一个TRUE / FALSE

any(do.call(paste, df1[1:2]) %in% do.call(paste, df2[1:2]))
#[1] TRUE

如果要删除df1中存在的df2中的行,可以使用anti_join中的dplyr

dplyr::anti_join(df1, df2, by = c('A', 'B'))
#  A  B  C
#1 1 10  6
#2 2 20  7
#3 3 30  8
#4 5 50 11

要获取公共行,可以使用semi_join / inner_join

dplyr::semi_join(df1, df2, by = c('A', 'B'))

答案 2 :(得分:2)

这是一种解决方案,返回df1df2中的行,列AB中匹配的行。

res <- apply(df2[1:2], 1, function(y){
  apply(df1[1:2], 1, function(x) all(x == y))
})

which(res, arr.ind = TRUE)
#     row col
#[1,]   4   2

w <- which(res, arr.ind = TRUE)
colnames(w) <- c('df1', 'df2')
w
#     df1 df2
#[1,]   4   2

答案 3 :(得分:0)

带有data.table加入的选项

library(data.table)
setDT(df1)[!df2, on = .(A, B)]
#   A  B  C
#1: 1 10  6
#2: 2 20  7
#3: 3 30  8
#4: 5 50 11

数据

df1 <- data.frame("A" = c(1,2,3,4,5), "B" = c(10,20,30,40,50), "C" = c(6,7,8,9,11))
df2 <- data.frame("A" = c(10,4,30,20,50), "B" = c(1,40,3,7,5), "C" = c(12,13,14,15, 15))