【问题标题】:Merge NA replacement合并 NA 替换
【发布时间】:2012-04-12 19:23:18
【问题描述】:

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

编辑想让它更具体

数据框 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

【问题讨论】:

  • 我建议您发布可重现的代码。您可以通过使用head(x dataframe, 10)head(y dataframe, 10) 以及您尝试使用的代码行来做到这一点。这对于诊断您的问题和提供准确有效的解决方案更有帮助。

标签: r


【解决方案1】:

我会分两步完成:

> 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

然后使用zoo 包中的na.locf

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

【讨论】:

  • 哇,太好了,谢谢。我需要关心数据框的顺序吗? na.locf 似乎没有考虑任何关于 Id 和年份的结构,而只是将数据框提升到以前的值。
  • 是的,na.locf 只是复制以前的值,而不考虑您的 Idyear。此外,如果 y 包含以前不匹配的年份(但将是 x 中条目的合适候选者),则不会捕获它。
  • 当您在data.frames 上调用merge 时,默认参数sort=TRUE 将按合并列排序(在您的情况下,您依赖于名称的交集) )。如果您希望它以不同的方式排序,您可以在 na.locf 步骤之前使用 order: out[order(out$var1),] 或其他方式进行排序。但你是对的,na.locf 只处理你发送的向量,不知道data.frame 的其余部分。
  • @BrianDiggs 好点!这根本不是一个可靠的答案,只是一个回答特定问题的答案。如果您担心y 中的额外行,您可以执行merge(..., all=T),然后开始拆分。您可能还想只在您希望有NA 的列上调用na.locf,而不是在所有列上。
  • 再次感谢所有帮助和 cmets。很高兴我决定在这里发布!
【解决方案2】:

这不使用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

【讨论】:

  • 也感谢这个例子。如果我想做一些稍微不同的事情,这两者都很好。
猜你喜欢
  • 2017-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-30
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
相关资源
最近更新 更多