2012-02-16 233 views
12

是否有快速找到矩陣B中哪些行存在於矩陣B中? 例如比較兩個矩陣之間的行

m1 = matrix(c(1:6), ncol=2, byrow = T); m2 = matrix(c(1:4), ncol=2, byrow=T); 

和結果將是1,2。

的矩陣不具有相同的行數(列數是一樣的),並且它們是有些大的 - 從10^6 - 10^7的行數。

做的最快的方法,我知道現在是:

duplicated(rbind(m1, m2)) 

TNX!

+2

您使用'duplicated'的解決方案還會返回在矩陣中重複的任何行,即使它僅出現在兩個矩陣中的一箇中。無論如何,@ MatthewDowle的回答非常好。 – 2012-02-16 19:00:43

+1

'data.table'可能會更快,因爲它不會使用'do.call(「paste」'在後臺。如果你更喜歡'重複'到'M2 [M1]'然後'重複(as.data.table (rbind(m1,m2)))''可能會更快,出於同樣的原因。有興趣看到你的時間。 – 2012-02-16 19:09:43

+0

@大衛哦是的,關於'重複'方法的好點。 – 2012-02-16 19:11:59

回答

21

該尺寸的一個快速方法應該是:

require(data.table) 
M1 = setkey(data.table(m1)) 
M2 = setkey(data.table(m2)) 
na.omit(
    M2[M1,which=TRUE] 
) 
[1] 1 2 
-1

我創造了這個功能,將返回原來的ID。例如,要將矩陣x與矩陣y匹配,它將返回y的匹配ID。

rowiseMatch2 <- function(x,y){ 
    require(data.table) 
    keycols <- colnames(x) 
    x <- cbind(x, id=1:nrow(x)) 
    y <- cbind(y, id=1:nrow(y)) 
    m1 = data.table(x) 
    setkeyv(m1, keycols) 
    m2 = data.table(y) 
    setkeyv(m2, keycols) 
    m1id <- m1$id 
    m2id <- m2$id 

    m1$id <- NULL 
    m2$id <- NULL 

    m <- na.omit(m2[m1,which=TRUE]) 
    mo <- m2id[m][order(m1id)] 

    if(length(mo) == nrow(x)){ 
    cat("Complete match!\n") 
    }else{ 
    cat("Uncomplete match, match percentage is:", round(length(mo)/nrow(x), 4)*100, "%\n") 
    } 
    return(as.integer(mo)) 
}