2017-04-04 47 views
3

我有兩個數據幀。第一個包含圖像的原始狀態,所有數據可用於從頭開始重建圖像(整個座標集及其顏色值)。基於多個非唯一列進行替換合併

然後我有第二個數據幀。這個更小,只包含有關更新狀態和原始狀態之間差異(所做更改)的數據。與關鍵幀相似的視頻編碼。

不幸的是,我沒有一個唯一的ID列來幫助我匹配它們。我有一個x列,我有一個y列,它們可以組成一個唯一的ID。

我的問題是:什麼是合併這兩個數據集,與值在原數據幀替換值的一種優雅的方式在「求差」的數據幀,其X y座標匹配。

下面是一些例子的數據來說明:

original <- data.frame(x = 1:10, y = 23:32, value = 120:129) 

    x y value 
1 1 23 120 
2 2 24 121 
3 3 25 122 
4 4 26 123 
5 5 27 124 
6 6 28 125 
7 7 29 126 
8 8 30 127 
9 9 31 128 
10 10 32 129 

並與更新的差的數據幀:

update <- data.frame(x = c(1:4, 8), y = c(2, 24, 17, 23, 30), value = 50:54) 

    x y value 
1 1 2 50 
2 2 24 51 
3 3 17 52 
4 4 23 53 
5 8 30 54 

所需的最終輸出應包含在原始數據幀的所有行。然而,在原始其中x和y座標都更新的相應的座標匹配的行,應該有他們與所述更新數據幀的值替換。這裏是所需的輸出:

original_updated <- data.frame(x = 1:10, y = 23:32, 
           value = c(120, 51, 122:126, 54, 128:129)) 

    x y value 
1 1 23 120 
2 2 24 51 
3 3 25 122 
4 4 26 123 
5 5 27 124 
6 6 28 125 
7 7 29 126 
8 8 30 54 
9 9 31 128 
10 10 32 129 

我試圖想出一個向量化的解決方案與索引一段時間,但我無法弄清楚。通常情況下,如果只有一列使用唯一的ID,我會使用%。但是這兩列不是唯一的。

一種解決方案是將它們視爲字符串或元組,並將它們組合爲一列作爲座標對,然後使用%in%。

但我很好奇是否有任何解決這個問題涉及索引與布爾向量。有什麼建議麼?

+2

隨着data.table,這是因爲原始'簡單[更新,就=(X,Y),值:= i.value]'(一旦它們都是數據。表)。一個類似的問題:http://stackoverflow.com/q/42587214/ data.table網站上的小插曲會讓你開始,如果你是新的包。 – Frank

回答

3

首先合併在保證從原來的所有值將出現一種方式:■

merged = merge(original, update, by = c("x","y"), all.x = TRUE) 

然後使用dplyr選擇updateoriginal如果可能的價值觀,和」價值另有:

library(dplyr) 
middle = mutate(merged, value = ifelse(is.na(value.y), value.x, value.y)) 
final = select(middle, x, y, value) 
+0

謝謝。如果你想保留所有的dplyr,你也可以'full_join(original,update,by =(「x」,「y」))''。我認爲這個答案是最實用的(與弗蘭克的評論一起),所以我接受了它! ** 42 - **的比賽解決方案一直忠於我所要求的。 – Lauler

1

匹配函數用於生成索引。需要nomatch參數來阻止data.frame.[<-左側的NA。我不認爲它是透明的合併,隨後更換,但我猜它會更快:

original[ match(update$x, original$x)[ 
             match(update$x, original$x, nomatch=0) == 
             match(update$y, original$y,nomatch=0)] , 
      "value"] <- 
    update[ which(match(update$x, original$x) == match(update$y, original$y)), 
      "value"] 

你可以看到區別:

> match(update$x, original$x)[ 
      match(update$x, original$x) == 
       match(update$y, original$y) ] 
[1] NA 2 NA 8 
> match(update$x, original$x)[ 
      match(update$x, original$x, nomatch=0) == 
       match(update$y, original$y,nomatch=0)] 
[1] 2 8 

的「內部」的匹配函數返回:

> match(update$y, original$y) 
[1] NA 2 NA 1 8 
> match(update$x, original$x) 
[1] 1 2 3 4 8