2015-11-30 154 views
1

我想要比較兩個數據幀: 如果兩個數據幀中的特定位置符合要求,則將「X」分配給單獨數據幀中的特定位置。R:比較矩陣中的字段

如何以有效的方式獲得預期的輸出?真正的data frame包含1000列,數千行至數百萬行。 我覺得data.table將是最快的選擇,但我沒有的把握如何data.table工作尚未

預期輸出:

> print(result) 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
# [1,] "A" "A" "O" "X" "X" "X" "X" "O" "O" 
# [2,] "A" "A" "O" "X" "X" "X" "X" "O" "O" 
# [3,] "A" "A" "O" "X" "X" "X" "X" "O" "X" 

我的代碼:

df1 <- structure(c(1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 
      2, 2, 2, 2, 3, 3, 3, 2, 0, 1), .Dim = c(3L, 9L), .Dimnames = list(
       c("A", "B", "C"), NULL)) 
df2 <- structure(c(1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 
      2, 2, 2, 2, 1, 3, 3, 4, 4, 2), .Dim = c(3L, 9L), .Dimnames = list(
       c("A", "B", "C"), NULL)) 

result <- matrix("O", nrow(df1), ncol(df1)) 


for (i in 1:nrow(df1)) 
{ 
    for (j in 3:ncol(df1)) 
    { 
    result[i,1] = c("A") 
    result[i,2] = c("A") 
    if (is.na(df1[i,j]) || is.na(df2[i,j])){ 
     result[i,j] <- c("N") 
    } 
    if (!is.na(df1[i,j]) && !is.na(df2[i,j]) && !is.na(df2[i,j])) 
    { 

     if (df1[i,j] %in% c("0","1","2") & df2[i,j] %in% c("0","1","2")) { 
     result[i,j] <- c("X") 
     } 
    } 
    } 
} 


print(result) 

編輯

我喜歡@David's和@ Heroka的解決方案。 在一個小數據集上,Heroka的解決方案速度是原來的125倍,而David的速度是原來的29倍。 這裏的風向標:

> mbm 
Unit: milliseconds 
      expr  min   lq  mean  median   uq  max neval 
     original 1058.81826 1110.481659 1131.81711 1112.848211 1124.775989 1428.18079 100 
      Heroka 8.46317 8.711986 9.03517 8.914616 9.067793 18.06716 100 
DavidAarenburg() 35.58350 36.660565 39.85823 37.061160 38.175700 53.83976 100 

非常感謝你們!

+2

這些都不是data.frames或data.tables,所以我刪除標記。您現在看到的矩陣。這些都是不同的「類」爲R. – Frank

+1

對象我已經編輯標題反映了這個。 – Heroka

+3

這不就是'結果[df1 <3&df2 <3] < - 「X」;結果[,1:2] < - 「A」;結果[is.na(df1)| is.na(df2)] < - 「N」'? –

回答

4

你有矩陣,而不是數據框。

一種方法可能是使用ifelse(和%的%的數值變量, 節省時間約50%,以避免時間轉換:

result <- ifelse(is.na(df1)|is.na(df2),"N", 
        ifelse(df1 %in% 0:2 & df2 %in% 0:2,"X","O")) 
    result[,1:2] <- "A" 
    result 

與感謝@DavidArenburg,更提高速度

result <- matrix("O",nrow=nrow(df1),ncol=ncol(df1)) 
result[is.na(df1) | is.na(df2)] <- "N" 
result[df1 < 3 & df2 < 3] <- "X" 
result[, 1:2] <- "A" 
+0

就像魅力@Heroka!我會等到接受你的答案,直到今天晚些時候,以更高性能的答案仍然出現! – Bas

+1

@Bas查看編輯。 – Heroka

+1

您是否在OPs模擬數據上的大數據集上測試了這一點? –