【问题标题】:R merge a particular column from one data frame to another according to its reference columnR根据其参考列将特定列从一个数据帧合并到另一个数据帧
【发布时间】:2014-07-28 19:46:03
【问题描述】:

我是 R 初学者。 我有两个巨大的数据框,我想在 hkdata.2 添加一个名为 Vaccine 的新列,该数据是根据 hkdata.2 上的 2 个参考列(hhID 和成员)从另一个 DF 依从性中获取的,有人可以帮我吗?

hkdata.2
hhID    member  T0  delta   X_hh    X_fm    ILI age
1          1    7      0    0       0        0  44
1          2    7      0    0       0        0  36
2          1    8      0    1       0        0  39
2          2    8      0    1       0        0  39

adherence
hhID member mask soap vaccine
1      0      1    0    1   
1      1      1    1    1
1      2      0    0    1
2      0      1    0    0
2      1      0    0    0
2      2      1    0    1

所以最后我可以得到这样的东西。 在 hkdata.2 中有一个称为疫苗的额外列

hkdata.2
hhID    member  T0  delta   X_hh    X_fm    ILI age vaccine
1          1    7      0    0       0        0  44    1
1          2    7      0    0       0        0  36    1
2          1    8      0    1       0        0  39    0
2          2    8      0    1       0        0  39    1

【问题讨论】:

  • 请检查 ?merge(), ?rbind_list from dplyr。这里,hhIDmember 列在两个数据集中都不是唯一的。
  • 所以在同一个hhID下,只有1个唯一#的成员

标签: r merge dataframe


【解决方案1】:

更新:v1.9.6 用于on= 语法。查看旧代码的历史记录。

require(data.table) # v1.9.6+
setDT(hkdata.2)[setDT(adherence), vaccine := i.vaccine, on=c("hhID", "member")]
#    hhID member T0 delta X_hh X_fm ILI age vaccine
# 1:    1      1  7     0    0    0   0  44       1
# 2:    1      2  7     0    0    0   0  36       1
# 3:    2      1  8     0    1    0   0  39       0
# 4:    2      2  8     0    1    0   0  39       1
  1. setDT通过引用将 data.frame 转换为 data.table。

  2. on= 指定的列执行连接。您需要的Note that this join is both a) fast *and* b) memory efficient. a) *fast* because they're binary search based joins, and no copy is being made here at all. Thevaccinecolumn is directly added to yourhkdata.2data.table. b) *memory efficient* because only the columnvaccine` 用于连接,而不是其他列(这对于非常大的数据集来说特别好)。


这是一个基准,假设每个 hhID 中有 100,000 个 hhIDs 和 200 个 members:

require(data.table) # v1.9.6
require(dplyr) # 0.4.3.9000

set.seed(98192L)
N = 40e6 # 40 million rows
hkdata.2 = data.frame(hhID   = rep(1:1e5, each=200), 
                      member = 1:200,
                      T0     = sample(10),
                      delta  = sample(0:1), 
                      X_hh   = sample(0:1), 
                      X_fm   = sample(0:1), 
                      ILI    = sample(0:1),
                      age    = sample(30:100, N/2, TRUE))

# let's go with 100,000 hhIDs and 400 members here:
adherence = data.frame(hhID    = rep(1:1e5, each=400), 
                       member  = 1:400,
                       mask    = sample(0:1),
                       soap    = sample(0:1),
                       vaccine = sample(0:1))

## dplyr timing
system.time(ans1 <- left_join(hkdata.2, select(adherence, -soap, -mask)))
#   user  system elapsed
# 16.977   2.163  19.605
## data.table timing
system.time(setDT(hkdata.2)[setDT(adherence), vaccine := i.vaccine, on=c("hhID", "member")])
#   user  system elapsed
#  1.186   0.233   1.427

dplyr 的内存使用峰值为 4.7GB,耗时 19.6 秒,而data.table 耗时 1.4 秒,内存使用峰值为 2.2GB。

总结:data.table 的速度提高了约 14 倍,内存效率提高了约 2.1 倍。

【讨论】:

  • 你需要setDT(adherence)吗?
  • 是的。如果没有,目前我们使用 as.data.table() 会产生一个副本。
  • 所以不推荐setDT(hkdata.2)[adherence, vaccine := i.vaccine, on=c("hhID", "member")]
  • 如果adherence很小,不是问题。
  • 快速提问 - 如果我想合并 更多 列怎么办?
【解决方案2】:

您可以使用plyr 库来执行此操作。

library(plyr)
new_frame=join(hkdata.2,adherence,by=c('hhID','member'))

【讨论】:

  • 是否有可能只是将疫苗列合并到数据框?
  • 是的,您可以对依从性数据框进行子集化,使其仅包含 ID 变量和疫苗变量。然后它只会附加那些。
【解决方案3】:
 library(dplyr)
 left_join(hkdata.2, adherence)
 #    Joining by: c("hhID", "member")
 #  hhID member T0 delta X_hh X_fm ILI age mask soap vaccine
 #1    1      1  7     0    0    0   0  44    1    1       1
 #2    1      2  7     0    0    0   0  36    0    0       1
 #3    2      1  8     0    1    0   0  39    0    0       0
 #4    2      2  8     0    1    0   0  39    1    0       1

如果你不需要masksoap

  left_join(hkdata.2, adherence) %>% select(-soap, -mask)

或者

  left_join(hkdata.2, adherence[,c("hhID", "member", "vaccine")])

【讨论】:

  • 因为当我输入 view(hkdata.2) 时,它仍然没有显示在数据框中。
  • @user3848693。假设您将结果存储在res &lt;- left_join(hkdata.2,....),您可以查看str(res)。另外,我想hkdata.2 是您的输入数据集之一..
猜你喜欢
  • 1970-01-01
  • 2022-01-20
  • 2019-10-17
  • 2021-10-09
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
相关资源
最近更新 更多