我有两个数据帧。
df1-
col1 col2 col3 col4 col5名称1 A 23 x y名称1 A 29 x y名称1 B 17 x y名称1 A 77 x y
df2-
col1 col2 col3B 17 LL1Z 193 KK177 LO9Y 80 LK2
如果df1的col2和col3不等于df2的col1和col2,我想从df1返回那些行。
输出应为-
col1 col2 col3 col4 col5名称1 A 23 x y名称1 A 29 x y
我找到的解决方案-
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万行。从过去两天开始,它一直在运行。有人能建议一个快速的方法吗?
尝试
> 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
可能让你头疼的是:
if (!found) out <- rbind(out, df1[i,])
您不断增长data.frame,这会导致操作系统为对象分配新的内存。我建议您预先分配一个有足够空间的data.frame,然后将正确的输出分配给正确的索引。这将使事情加速几个数量级。
此外,R经常被矢量化,因此不需要显式循环。例如,请参阅@ttmaccer的答案。你也可以看看data.table
,它对于这类操作来说是闪电般的快。