1

我有 2 个数据框。

df1-

col1 col2 col3 col4 col5
名称1 A 23 xy
名称1 A 29 xy
名称1 B 17 xy
名称1 A 77 xy

df2-

   
col1 col2 col3
B 17 LL1
Z 193 KK1       
77 LO9
Y 80 LK2       

如果 df1 的 col2 和 col3 不等于 df2 的 col1 和 col2,我想从 df1 返回这些行。

输出应该是 -

col1 col2 col3 col4 col5
名称1 A 23 xy
名称1 A 29 xy

我发现的解决方案-

unique.rows <- function (df1, df2) {   
  out <- NULL
  for (i in 1:nrow(df1)) {
    found <- FALSE
    for (j in 1:nrow(df2)) {
      if (all(df1[i,2:3] == df2[j,1:2])) {
        found <- TRUE
        break
      }
    }
    if (!found) out <- rbind(out, df1[i,])
  }
  out
}

该解决方案运行良好,但最初,我申请的是小型数据框。现在我的 df1 有大约 10k 行,而 df2 有大约 700 万行。它刚刚从过去 2 天开始运行。谁能建议一个快速的方法来做到这一点?

4

2 回答 2

3

尝试

> df1[!paste(df1$col2,df1$col3)%in%paste(df2$col1,df2$col2),]
   col1 col2 col3 col4 col5
1 name1    A   23    x    y
2 name1    A   29    x    y
于 2012-07-17T14:57:05.017 回答
2

可能咬你的是这条线:

if (!found) out <- rbind(out, df1[i,])

你不断地增长一个 data.frame,这会导致操作系统为对象分配新的内存。我建议您预先分配一个具有足够空间的 data.frame,然后将正确的输出分配给正确的索引。这应该会加快几个数量级的速度。

此外,R 经常矢量化,不需要显式循环。例如,参见@ttmaccer 的答案。您还可以查看data.table,这对于此类操作来说非常快。

于 2012-07-17T14:54:20.263 回答