通过引用更新 data.table,但在使用优先向量存在重复项时仅填充某些行
Update data.table by reference but populate only certain rows when duplicates are present using a prioritized vector
我不太清楚标题的措辞,但这就是我想做的。我想使用 dt2
中的列来增加数据 table dt1
。在 dt1
中,我 updating/merging 所在的列中有重复数据。我的目标是仅在满足条件时才重复填充 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")
我尝试用 NA
覆盖合并的 dt3
(或更新的 dt1
)的行,但我不想有数据:
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) 这种方法需要 hard-coding 我想保留的案例。在我的 real-world 应用程序中,我将循环这种类型的数据准备,条件值将发生变化。我知道更新数据的优先级 table 不过:
order_to_populate_dups <- c("update1", "update2", "update3")
换句话说,我想要一个代码来增长数据 table 如下:
1)当没有重复时,按引用添加列(或合并)正常
2) 当 id
变量下存在重复时,查看 condition_var
2a) 如果看到update1
添加数据,如果没有,下一步
2b) 如果看到update2
添加数据,如果没有,下一步
2c) 如果看到 update3
添加数据,如果没有,下一步,...
我无法在 SO 中找到此问题的解决方案。如果这是重复的,请告诉我。
谢谢!
如果我理解你的例子是否正确,请告诉我。如果需要,我可以更改解决方案。
# 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)]
您是否在寻找类似的东西:
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
.
的每组第一行执行update join
我不太清楚标题的措辞,但这就是我想做的。我想使用 dt2
中的列来增加数据 table dt1
。在 dt1
中,我 updating/merging 所在的列中有重复数据。我的目标是仅在满足条件时才重复填充 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")
我尝试用 NA
覆盖合并的 dt3
(或更新的 dt1
)的行,但我不想有数据:
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) 这种方法需要 hard-coding 我想保留的案例。在我的 real-world 应用程序中,我将循环这种类型的数据准备,条件值将发生变化。我知道更新数据的优先级 table 不过:
order_to_populate_dups <- c("update1", "update2", "update3")
换句话说,我想要一个代码来增长数据 table 如下:
1)当没有重复时,按引用添加列(或合并)正常
2) 当 id
变量下存在重复时,查看 condition_var
2a) 如果看到update1
添加数据,如果没有,下一步
2b) 如果看到update2
添加数据,如果没有,下一步
2c) 如果看到 update3
添加数据,如果没有,下一步,...
我无法在 SO 中找到此问题的解决方案。如果这是重复的,请告诉我。
谢谢!
如果我理解你的例子是否正确,请告诉我。如果需要,我可以更改解决方案。
# 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)]
您是否在寻找类似的东西:
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
.