首页 > 解决方案 > 通过引用更新 data.table,但仅在存在重复项时使用优先级向量填充某些行

问题描述

我不太知道如何写标题,但这就是我想要做的。我想dt1使用来自dt2. 在dt1中,我正在更新/合并的列中有重复的数据。dt1我的目标是仅在满足另一个变量指定的条件时才在重复项中填充新列。让我证明我的意思:

library(data.table)


dt1 <- data.table(common_var = c(rep("a", 3), rep("b", 2)),
                  condition_var = c("update1", rep(c("update2", "update3"), 2)),
                  other_var = 1:5)


dt2 <- data.table(common_var = c("a", "b", "C", "d"),
                  new_var1 = 11:14,
                  new_var2 = 21:24)

# What I want to obtain is the following
dt_goal <- data.table(common_var = dt1$common_var,
                      condition_var = dt1$condition_var,
                      other_var = dt1$other_var,
                      new_var1 = c(11, NA, NA, 12, NA),
                      new_var2 = c(21, NA, NA, 22, NA))
dt_goal

通过引用更新或合并填充所有匹配的行(如预期的那样),但这不是我想要的:

# Updating by reference populates all the duplicate rows as expected
# (doesn't work for my purpose)
dt1[, names(dt2) := as.list(dt2[match(dt1$common_var, dt2$common_var),])]

# merging also populates duplicate rows as expected.
# dt3 <- merge(dt1, dt2, by="common_var")

我尝试用s 覆盖我不想拥有数据的合并dt3(或更新dt1)行:NA

dt3 <- dt3[which(alldup(dt3$common_var) & dt3$condition_var %in% c("update2", "update3")), names(dt2)[2:3] := NA]
dt3

上面代码中的逻辑发现重复and不需要的条件情况,并将选定的列替换为NA. 这部分有效,但有两个问题:

1) 如果要保留的值 ( update1) 不存在于其他重复行中(b在我的示例中),它们也会被删除

2)这种方法需要对我想要保留的案例进行硬编码。在我的实际应用程序中,我将循环这种类型的数据准备,条件值会发生变化。我知道更新数据表的优先级:

order_to_populate_dups <- c("update1", "update2", "update3")

换句话说,我想要一个代码来增长数据表,如下所示:

1) 无重复时,按引用(或合并)正常添加列

2)当id变量下存在重复项时,请查看condition_var

2a)如果你看到update1添加数据,如果没有,下一步

2b)如果你看到update2添加数据,如果没有,下一步

2c) 如果您看到update3添加数据,如果没有,下一步,...

我在 SO 中找不到此问题的解决方案。请让我知道这是否以某种方式重复。

谢谢!

标签: rmergedata.tableconditional-statementspass-by-reference

解决方案


您是否正在寻找类似的东西:

cols <- paste0("new_var", 1:2)
remap <- c(update1=1, update2=2, update3=3)
dt1[, rp := remap[condition_var]]

setkey(dt1, common_var, rp)
dt1[rowid(common_var)==1L, (cols) := 
    dt2[.SD, on=.(common_var), mget(paste0("i.",cols))]

说明:您可以使用factor或向量将您的字符向量重新映射为可以相应排序的内容。然后setkey在对每组的第一行执行更新连接之前使用 对数据进行排序common_var


推荐阅读