通过引用更新data.table,但是当使用优先级向量重复出现时仅填充某些行

问题描述 投票:0回答:1

我不太清楚标题的字眼,但这就是我想要做的。我想使用dt1中的列来扩展数据表dt2。在dt1中,我正在更新/合并的列中存在重复的数据。我的目标是仅在满足条件的情况下才将dt1中的新列填充为重复项由另一个变量指定。让我演示一下我的意思:

library(data.table)


dt1 <- data.table(common_var = c(rep("a", 3), rep("b", 2)),
                  condition_var = c("keep1", rep(c("keep2", "keep3"), 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 = 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")

我尝试用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中找到此问题的解决方案。请让我知道这是否重复。

谢谢!

r merge data.table conditional-statements pass-by-reference
1个回答
0
投票

请让我知道我是否正确理解了您的示例。如果需要,我可以更改解决方案。

# order dt1 by the common variable and 
setorder(dt1, common_var, condition_var) condition
# calculate row_id for each group (grouped by common_var)
dt1[, row_index := rowid(common_var)] 
# assume dt2 has only one row per common_var
dt2[, row_index := 1]

# left join on common_var and row_index, reorder columns.
dt3 <- dt2[dt1, on = c('common_var', 'row_index')][, list(common_var, condition_var, other_var, new_var1, new_var2)]
© www.soinside.com 2019 - 2024. All rights reserved.