【发布时间】:2011-12-05 10:06:04
【问题描述】:
这是我第一次在这里发帖,请多多关照;-)
编辑 在我有机会做出向我建议的更改之前,我的问题已经结束。所以我现在正在努力做得更好,感谢到目前为止所有回答的人!
问题
如何根据可用的所有属性(即所有列)识别数据框x.1中不包含在数据框x.2中的记录/行以最有效的方式?
示例数据
> x.1 <- data.frame(a=c(1,2,3,4,5), b=c(1,2,3,4,5))
> x.1
a b
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
> x.2 <- data.frame(a=c(1,1,2,3,4), b=c(1,1,99,3,4))
> x.2
a b
1 1 1
2 1 1
3 2 99
4 3 3
5 4 4
期望的结果
a b
2 2 2
5 5 5
迄今为止最好的解决方案
Brian Ripley 教授和 Gabor Grothendieck 教授
> fun.12 <- function(x.1,x.2,...){
+ x.1p <- do.call("paste", x.1)
+ x.2p <- do.call("paste", x.2)
+ x.1[! x.1p %in% x.2p, ]
+ }
> fun.12(x.1,x.2)
a b
2 2 2
5 5 5
> sol.12 <- microbenchmark(fun.12(x.1,x.2))
> sol.12 <- median(sol.12$time)/1000000000
> sol.12
> [1] 0.000207784
我的blog提供了迄今为止测试过的所有解决方案的集合@
最终编辑 2011-10-14
这是封装在函数“mergeX()”中的最佳解决方案:
setGeneric(
name="mergeX",
signature=c("src.1", "src.2"),
def=function(
src.1,
src.2,
...
){
standardGeneric("mergeX")
}
)
setMethod(
f="mergeX",
signature=signature(src.1="data.frame", src.2="data.frame"),
definition=function(
src.1,
src.2,
do.inverse=FALSE,
...
){
if(!do.inverse){
out <- merge(x=src.1, y=src.2, ...)
} else {
if("by.y" %in% names(list(...))){
src.2.0 <- src.2
src.2 <- src.1
src.1 <- src.2.0
}
src.1p <- do.call("paste", src.1)
src.2p <- do.call("paste", src.2)
out <- src.1[! src.1p %in% src.2p, ]
}
return(out)
}
)
【问题讨论】:
-
这不是一个真正的问题。您针对自己的问题发布了 8 种不同的解决方案,其中最好的(由 Brian Ripley 教授撰写)只有三行 Base R 代码,并且已经打包成一个函数。你还想要什么?
-
@Andrie,他可能想要我的解决方案? :-))
-
@Andrie:我害怕发生这样的事情 ;-) 仍然认为我确实提出了一个问题,为什么不能将问题与可能的解决方案的集合联系起来,而不是解决方案分散在各处这个地方,因为每个人都用不同的措辞来描述他/她所追求的?只是想帮助别人一点...
-
我认为结束这个问题是一个非常不具建设性和愚蠢的举动。给他机会改进这个问题。这样你就强迫他开始一个新的。这样更好吗?
-
这个问题仍然需要投票才能重新开放。我建议编辑问题(添加一些解决方案)并清楚说明您的问题是什么,然后标记它。
标签: r join merge match dataframe