2012-04-12 141 views
1

我试图合并两个数据帧在一个唯一的ID和年份。在SQL语言中,我试图做一个左外部连接,所以在合并中是all.x = TRUE。 y数据框的某些元素在x DF中没有所有的值(唯一标识,年份组合)。在缺少匹配的情况下,我想合并具有与x数据帧中相同的唯一标识的y数据框中的行,但是使用了我在缺失之前的第一年。有关如何进行此合并的任何建议?非常感谢!合并NA替换

编辑想让它更加具体

数据帧X:

Id year var1 
1 2010 100 
1 2011 105 
1 2012 110 
2 2010 100 
2 2011 105 
2 2012 106 

数据帧Y:

Id year var2 var3 
1 2010 5  7 
1 2011 10  8 
2 2010 9  6 

所需的合并:

Id year var1 var2 var3 
1 2010 100  5  7 
1 2011 105  10  8 
1 2012 110  10  8 
2 2010 100  9  6 
2 2011 105  9  6 
2 2012 106  9  6 
+0

我会建议你发布一个可重复的代码。你可以通过使用'head(x dataframe,10)'和'head(y dataframe,10)'和你试图使用的代码行来实现。这对于诊断问题和提供准确有效的解决方案更有帮助。 – 2012-04-12 19:33:04

回答

2

我做这两个步骤:

> out <- merge(x, y, all.x=T) 
> out 
    Id year var1 var2 var3 
1 1 2010 100 5 7 
2 1 2011 105 10 8 
3 1 2012 110 NA NA 
4 2 2010 100 9 6 
5 2 2011 105 NA NA 
6 2 2012 106 NA NA 

然后使用na.locfzoo包:

library(zoo) 

> apply(out, 2, na.locf) 
    Id year var1 var2 var3 
[1,] 1 2010 100 5 7 
[2,] 1 2011 105 10 8 
[3,] 1 2012 110 10 8 
[4,] 2 2010 100 9 6 
[5,] 2 2011 105 9 6 
[6,] 2 2012 106 9 6 

,这可以被强制转换为data.frame很轻松了。

> as.data.frame(apply(out, 2, na.locf)) 
    Id year var1 var2 var3 
1 1 2010 100 5 7 
2 1 2011 105 10 8 
3 1 2012 110 10 8 
4 2 2010 100 9 6 
5 2 2011 105 9 6 
6 2 2012 106 9 6 
+0

哇,这很好,谢谢。我需要关心数据框的顺序吗?看起来na.locf似乎没有考虑到任何关于Ids和年的结构,只是将数据框提高到之前的值。 – 2012-04-12 20:04:43

+0

是的,'na.locf'只是复制之前的值而不考虑你的'Id'或'year'。另外,如果'y'包含一个以前没有匹配的年份(但是将会成为'x'中的条目的合适候选者),这不会被捕获。 – 2012-04-12 20:09:20

+0

当你在'data.frames'上调用'merge'时,有一个默认参数'sort = TRUE',它将按合并列进行排序(在你的情况下,你依赖于这些名称的交集)。如果你想以不同的方式排序,你可以在使用'order'的'na.locf'步骤之前完成:'out [order(out $ var1),]'或者其他。但是你是正确的,'na.locf'只能处理你发送的矢量,并且不知道'data.frame'的其余部分。 – Justin 2012-04-12 20:11:25

1

这不使用merge,而是通过x一个行循环在时间找到合适的匹配在y。可能效率不高,但有效。

do.call(rbind, 
    lapply(seq(length=nrow(x)), function(r) { 
    yid <- y[y$Id==x$Id[r],] 
    yeardiff <- x$year[r] - yid$year 
    yeardiff[yeardiff < 0] <- NA 
    cbind(x[r,], yid[which.min(yeardiff),]) 
})) 

结果是

Id year var1 Id year var2 var3 
1 1 2010 100 1 2010 5 7 
2 1 2011 105 1 2011 10 8 
3 1 2012 110 1 2011 10 8 
4 2 2010 100 2 2010 9 6 
5 2 2011 105 2 2010 9 6 
6 2 2012 106 2 2010 9 6 
+0

感谢这个例子。它很高兴有两个以防万一我想做一些稍微不同的事情。 – 2012-04-12 20:17:09