r - 在 R 中合并时有没有办法更新现有变量?

标签 r dataframe data-structures merge

我有两个数据集想要在变量 id 上合并,其中一个数据集有两个可能的 id,例如:

df1 <- data.frame(id = c('a', 'b', 'c', 'q', 'z'),
                  id2 = c('NA', 'g', 'NA', 'd', 'e'),
                  var1 = 1:5,
                  var3 = c('hi', 'hello', 'bonjour', 'howdy', 'hi'))
df2 <- data.frame(id = c('a', 'b', 'c', 'd', 'e'),
                  var2 = 6:10,
                  var4 = 20:24)

我目前将这些数据集合并到主链接变量上:

merge1 <- merge(x = df1,
                y = df2,
                by = 'id',
                all = TRUE)

我需要重新合并第一个数据框中具有第二个 id 但在初始合并中不匹配的行,因此我将它们放入单独的数据框中,将它们从完全匹配的数据集中取出,然后将两者合并:

df1.remerge <- merge1[which(!is.na(merge1$id2) &
                              is.na(merge1$var2)),] 
df1.remerge$id <- df1.remerge$id2

merged <- merge1[which(is.na(merge1$id2) |
                       !is.na(merge1$var2)),]

merge2 <- merge(x = df1.remerge,
                y = merged,
                by = 'id',
                all = TRUE,
                suffixes = c('.m1', '.m2'))
# where .m1 = the remerged obs from df1 & .m2 = the original merged obs

不过,这会创建两组相同的变量(即我最终得到两个 var1 和两个 var2)。我当然可以手动组合变量,但我不想这样做,因为我的实际数据非常大(想想数百万个观察值和 30-40 个变量),这似乎效率相当低。

最终我想要一个大致如下所示的数据集:

want.final <- data.frame(id = c('a', 'b', 'c', 'd', 'e'),
                         var1 = 1:5,
                         var2 = 6:10,
                         var3 = c('hi', 'hello', 'bonjour', 'howdy', 'hi'),
                         var4 = 20:24)

但是我用这个方法得到的是这样的:

get.final <- data.frame(id = c('a', 'b', 'c', 'd', 'e'),
                        var1.m1 = c('NA', 'NA', 'NA', 4, 5),
                        var1.m2 = c(1, 2, 3, 'NA', 'NA'),
                        var2.m1 = c('NA', 'NA', 'NA', 'NA', 'NA'),
                        var2.m2 = c(6, 7, 8, 9, 10),
                        var3.m1 = c('NA', 'NA', 'NA', 'howdy', 'hi'),
                        var3.m2 = c('hi', 'hello', 'bonjour', 'NA', 'NA'),
                        var4.m1 = c('NA', 'NA', 'NA', 'NA', 'NA'),
                        var4.m2 = c(20, 21, 22, 23, 24))

有谁知道如何重新合并这些观察结果并更新 master/x 数据集中缺少的现有变量,而 using/y 中没有缺少这些变量?在理想的情况下,我希望 Stata 的 mergeupdate 选项能够做到这一点。

最佳答案

如果我理解正确,OP希望找到df1$iddf2$id之间的匹配行。对于 df1 中未找到匹配项的行,第二次尝试应在替代 id df1$id2 之间找到匹配行df2$id。此外,数据集非常大(包含数百万行),并且 OP 或多或少仅限于基本 R。

基础R

因此,我们可以先解决 df1 中的重复 id 列,然后再进行单次合并,而不是对数百万行的数据集进行多次合并:

id1 <- df2$id[match(df1$id,  df2$id)]
id2 <- df2$id[match(df1$id2, df2$id)]
df1$id <- ifelse(is.na(id1), id2, id1)
df1$id2 <- NULL
merge(df1, df2)
  id var1    var3 var2 var4
1  a    1      hi    6   20
2  b    2   hello    7   21
3  c    3 bonjour    8   22
4  d    4   howdy    9   23
5  e    5      hi   10   24

说明

  • 首先,我们检查 df1$id 是否包含在 df2$id 中,返回 id1

    [1] "a" "b" "c" NA  NA
    
  • 然后,我们检查 df1$id2 是否包含在 df2$id 中,返回 id2

    [1] NA  NA  NA  "d" "e"
    
  • 现在,我们可以合并 id1id2,即,我们成对选择第一个非 NA 值,然后替换 df1 中的 id 列,使其变为

    [1] "a" "b" "c" "d" "e"
    
  • df1 中的 id2 列已被删除,因为不再需要它。

  • 最后,修改后的df1df2合并到id列上。

编辑:data.table方法

正如OP指出的,他的生产数据集由数百万个观察值和30-40个变量组成,可能值得考虑方法。 具有 := 赋值运算符,允许通过引用快速更新列。

使用data.table,上述方法可以通过以下方式实现

library(data.table)
setDT(df1)
setDT(df2)
df2[df1[, `:=`(id = fcoalesce(df2[df1, on = "id", x.id], df2[df1, on = "id==id2", x.id]),
          id2 = NULL)], on = "id"]

关于r - 在 R 中合并时有没有办法更新现有变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69031593/

相关文章:

r - 使用 purrr/tidyverse 按名称字母顺序对列表进行排序

xml - htmlParse 无法加载外部实体

c - 将中缀转换为后缀时出现段错误

r - 在 ggplot2 中打破 Y Axis

r - 在一组中找到重叠时间

python - 合并具有特定条件的数据帧

python - 在 pandas dataframe 中环绕索引进行切片的好方法

python - pandas Dataframe 中 mode() 的输出不舒服

c - 我不明白的预处理器宏

javascript - 正确的扁平化数据模型和 noSQL 数据结构