【问题标题】:rbind two tables and fill NA's rows with values having same variablerbind 两个表并用具有相同变量的值填充 NA 的行
【发布时间】:2018-07-16 10:31:35
【问题描述】:

我将根据示例数据向您解释我的问题。这是第一个表(df1)

  x x1 y  z
1 1 10 a 11
2 3 11 b 13
3 5 10 c 15
4 7 11 d 17
5 9 10 e 19

这里是dput() 版本:

structure(list(x = c(1, 3, 5, 7, 9), x1 = c(10, 11, 10, 11, 10
), y = structure(1:5, .Label = c("a", "b", "c", "d", "e"), class = "factor"), 
    z = c(11, 13, 15, 17, 19)), .Names = c("x", "x1", "y", "z"
), row.names = c(NA, -5L), class = "data.frame")

和第二个表(df2)

  x x1
1 2 10
2 3 60

dput():

structure(list(x = c(2, 3), x1 = c(10, 60)), .Names = c("x", 
"x1"), row.names = c(NA, -2L), class = "data.frame")

我现在需要绑定这两个表的行,并用 df1 中的值填充缺失的列值。让我根据这两个表为您解释一下。

起初我使用smartbind()库中的smartbind()函数:

library(gtools)
data <- smartbind(df1, df2)

我得到的结果是这样的:

 x x1    y  z
 1 10    a 11
 3 11    b 13
 5 10    c 15
 7 11    d 17
 9 10    e 19
 2 10 <NA> NA
 3 60 <NA> NA

所以我想填充出现在 df2 行中的所有 NA 值,如果 x 相同,则使用 df1 值。在这种情况下,它看起来像这样:

 x x1    y  z
 1 10    a 11
 3 11    b 13
 5 10    c 15
 7 11    d 17
 9 10    e 19
 2 10 <NA> NA
 3 60    b 13

在我的原始数据集中,我确实有大约 280 列!感谢您的帮助

有没有更优雅的方法来做到这一点,而不是加入两个数据帧,然后使用 rbind()

【问题讨论】:

  • 对我来说似乎是重复的:首先您必须通过x 合并并选择所有df2 记录,然后才使用rbindHow to join (merge) data frames (inner, outer, left, right)?
  • 还有更优雅的方法吗?我知道我可以通过合并然后使用 rbind 来做到这一点,但是如果我有巨大的表(列 > 280,行 > 10000),它似乎并不优雅和高效

标签: r


【解决方案1】:

首先您可以合并 df1 中缺少的 df2 列,只保留多余的列(yz,以及来自 df1 的键列 x):

df2 = merge(df2,df1[,c("x","y","z")],by="x",all.x=T)

然后 rbind df1 和 df2:

> rbind(df1,df2)
  x x1    y  z
1 1 10    a 11
2 3 11    b 13
3 5 10    c 15
4 7 11    d 17
5 9 10    e 19
6 2 10 <NA> NA
7 3 60    b 13

【讨论】:

  • 使用df1[, -2]
  • 感谢您的回答,但是我正在寻找更优雅的方式来做到这一点,也许是 data.table?
  • @PoGibas 你是对的,但是保持这样,因为列名对于演示目的更容易理解。
  • @Mal_a 您可以根据自己的喜好将上述过程封装在一个函数中,并提出您自己的优雅解决方案 :) (PS:我猜列 > 280,行 > 10000 没什么大不了的合并和 rbind)
【解决方案2】:

或使用tidyverse

library(tidyverse)
df1 %>% 
   select(-x1) %>% 
   right_join(df2) %>%
   bind_rows(df1, .)
#  x x1    y  z
#1 1 10    a 11
#2 3 11    b 13
#3 5 10    c 15
#4 7 11    d 17
#5 9 10    e 19
#6 2 10 <NA> NA
#7 3 60    b 13

data.table

nm1 <- setdiff(names(df1), c('x', 'x1'))
setDT(df2)[df1, (nm1) := mget(nm1), on = .(x)]
rbind(df1, df2)
#   x x1    y  z
#1: 1 10    a 11
#2: 3 11    b 13
#3: 5 10    c 15
#4: 7 11    d 17
#5: 9 10    e 19
#6: 2 10 <NA> NA
#7: 3 60    b 13

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2013-05-09
    • 2018-06-04
    • 2021-03-22
    • 1970-01-01
    • 2022-08-22
    相关资源
    最近更新 更多