2012-02-16 47 views
12

Có cách nào nhanh chóng để tìm ra các hàng nào trong ma trận A có mặt trong ma trận B không? ví dụ:So sánh các hàng giữa hai ma trận

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

và kết quả sẽ là 1, 2.

Các ma trận không có cùng số hàng (số cột là như nhau), và họ là hơi lớn - từ 10^6 - 10^7 số hàng.

Cách nhanh nhất để làm việc đó, mà tôi biết bây giờ, là:

duplicated(rbind(m1, m2)) 

Tnx!

+2

Giải pháp của bạn với 'trùng lặp' cũng sẽ trả lại bất kỳ hàng nào được lặp lại trong ma trận, ngay cả khi chỉ xuất hiện trong một trong hai ma trận. Dù sao, câu trả lời của @ MatthewDowle thật tuyệt vời. –

+1

'data.table' có thể nhanh hơn vì nó không sử dụng' do.call ("paste" 'dưới mui xe. Nếu bạn thích' duplicateated' thành 'M2 [M1]' thì 'duplicate (as.data.table (rbind (m1, m2))) 'có thể nhanh hơn, vì lý do tương tự. Quan tâm để xem timings của bạn –

+0

@David Ồ vâng, điểm tốt về cách tiếp cận' trùng lặp' –

Trả lời

21

Một cách nhanh chóng cho rằng kích thước nên là:

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

Tôi tạo ra chức năng này sẽ trở lại ID gốc. Ví dụ bạn muốn khớp ma trận x với ma trận y, nó sẽ trả về ID khớp của y.

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)) 
}