【发布时间】:2020-04-24 11:15:37
【问题描述】:
我想从data.table 计算一个聚合值并用它来替换原始值。我尝试了以下方法
library(data.table)
(DT <- data.table(grp = rep(LETTERS[1:3], 3),
val = 1:9,
val2 = rep(letters[24:26], each = 3)))
# grp val val2
# 1: A 1 x
# 2: B 2 x
# 3: C 3 x
# 4: A 4 y
# 5: B 5 y
# 6: C 6 y
# 7: A 7 z
# 8: B 8 z
# 9: C 9 z
(agg <- DT[, .SD[which.min(val)], grp])
# grp val val2
# 1: A 1 x
# 2: B 2 x
# 3: C 3 x
DT[, val3 := "New Value"]
agg[DT, on = "grp"][, .SD, .SDcols = !patterns("^i\\.")]
# grp val val2 val3
# 1: A 1 x New Value
# 2: B 2 x New Value
# 3: C 3 x New Value
# 4: A 1 x New Value
# 5: B 2 x New Value
# 6: C 3 x New Value
# 7: A 1 x New Value
# 8: B 2 x New Value
# 9: C 3 x New Value
虽然这种方法在这个玩具示例中有效,但我有几个问题:
-
我想首先避免链接以避免大量复制未使用的列(我的真实数据集相当大
2e5 x 200)引用data.table FAQ 1.10:因此,我们强烈建议使用 X[Y, j] 而不是 X[Y]
将
.SD部分放入第一个子集中的j插槽,不起作用agg[DT, .SD, on = "grp", .SDcols = !patterns("^i\\.")] # Error in do_patterns(colsub, names_x) : Pattern not found: [^i\.] -
patterns方法感觉有点老套,它依赖于假设data.table将始终在Y的列前面加上i.。如果包维护者出于某种原因更改它,我的代码就会中断。 - 我还在学习
data.table,我想了解data.table中解决此问题的最“惯用”方法是什么
如何解决此问题,同时避免制作不必要的副本以节省资源?
注意。重要的是:我不想通过引用更改DT 中的值。
【问题讨论】:
-
可能类似于
agg[DT, on=.(grp), mget(paste0("i.", names(DT)))]。看到这些开创性的帖子:stackoverflow.com/questions/29321218/… 和 stackoverflow.com/questions/30468455/…
标签: r data.table