2014-03-26 48 views
5

我寫了下面的函數,它的工作原理。然而,當df1具有1700行時,它非常緩慢,並且df2具有70000行。無論如何提高效率?檢查數據幀的每一行是否包含在另一個數據幀中

rowcheck <- function(df1, df2){ 
     apply(df1, 1, function(x) any(apply(df2, 1, function(y) all(y==x)))) 
} 

我寫了這個功能應用到的一個例子是:我要檢查在DF1各行是否包含在DF2行:

df1=data.frame(a=c(1:3),b=c("a","b","c")) 
df2=data.frame(a=c(1:6),b=rep(c("a","b","c"),2)) 

對於DF1的每一行,我想檢查它是否包含在df2中的一行中。我想返回函數作爲長度爲nrow(df1)的邏輯向量。

謝謝你的幫助。

+1

也許你可以試試'all(y%in%x)'?我建議你提供一個簡單的例子來說明你的問題。 http://download.microsoft.com/zh-cn/kb/5963269/how-to-make-a-great-r-reproducible-example –

+0

** dplyr **軟件包有一個'setdiff'方法用於您可能會調查的data.frame。 – joran

+0

否則我會粘貼每行的值,並使用u < - do.call(paste,df1)和v < - do.call(paste,df2),然後在%v中執行u%,但我不檢查計算時間 – droopy

回答

6

一種方法是將行粘貼在一起,並將其與%in%進行比較。根據要求,結果是邏輯向量長度爲​​nrow(df1)

do.call(paste0, df1) %in% do.call(paste0, df2) 
# [1] TRUE TRUE TRUE 
+0

謝謝@RichardScriven。所以基本上你將列維數減少到1,所以你可以在%中使用%。所以我猜%%只適用於一維變量檢查。 –

6

嘗試:

Filter(function(x) x > 0, which(duplicated(rbind(df2, df1))) - nrow(df2)) 

它會告訴你這df1行號發生在df2。如果你想邏輯值的像理查德·斯科利文的回答原子載體,嘗試

duplicated(rbind(df2, df1))[-seq_len(nrow(df2))] 

它也更快,因爲它使用了一個內部的C函數duplicated(我的是rowcheck2

> microbenchmark(rowcheck(df1, df2), rowcheck2(df1, df2)) 
Unit: milliseconds 
       expr  min  lq median  uq  max neval 
    rowcheck(df1, df2) 2.045210 2.169182 2.328296 3.539328 13.971517 100 
    rowcheck2(df1, df2) 1.046207 1.112395 1.243390 1.727921 7.442499 100 
0

只是想給我這個查詢兩美分。基於plyr的解決方案:

nrow(match_df(df2, df1)) 

..將檢查DF1的每一行對DF2(相對於所有列),給你包含在DF2 DF1的行數。

相關問題