2017-04-04 92 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