我正在尝试与此问题做同样的事情:Add max value to a new column in R,但是,我想直接传递变量而不是列名,因此我不会将列名硬编码到公式中。
示例代码:
a <- c(1,1,2,2,3,3)
b <- c(1,3,5,9,4,NA)
d <- data.table(a, b)
d
a b
1 1
1 3
2 5
2 9
3 4
3 NA
我可以得到这个:
a b max_b
1 1 3
1 3 3
2 5 9
2 9 9
3 4 4
3 NA 4
通过对其进行硬编码:setDT(d)[, max_b:= max(b, na.rm = T), a]
,但我想改成这样:
cn <- "b"
setDT(d)[, paste0("max_", cn):= max(cn, na.rm = T), a]
但是,这不起作用,因为它在max()
内部求值为字符的最大值,而不是列的最大值。并且它的结果是名为max_b
的列,其中包含值b
,因为max("b") = "b"
。我知道为什么会这样,我只是不知道解决方法。
对此有什么解决方案?
注意:我标记的上述堆栈问题被标记为重复并关闭,但是我选择了该问题,因为我在代码中使用了该问题的可接受答案。我也不是100%同意这还是一个重复的问题。
答案 0 :(得分:2)
尝试setDT(d)[, paste0("max_", cn) := eval(parse(text = max(eval(parse(text = cn))))), a]
# output
a b max_b
1: 1 1 3
2: 1 3 3
3: 2 5 9
4: 2 9 9
5: 3 4 4
# example with missing values
a <- c(1,1,2,2,3,3)
b <- c(1,3,5,9,4,NA)
d <- data.table(a, b)
cn <- "b"
setDT(d)[, paste0("max_", cn) := eval(parse(text = max(eval(parse(text = cn)),
na.rm = TRUE))), a]
#output
a b max_b
1: 1 1 3
2: 1 3 3
3: 2 5 9
4: 2 9 9
5: 3 4 4
6: 3 NA 4
答案 1 :(得分:0)
一个选项是在.SDcols
中指定变量,然后在.SD
(Data.table的子集)上应用该函数。
d[, paste0("max_", cn) := lapply(.SD, max, na.rm = TRUE), by = a, .SDcols = cn]
d
# a b max_b
#1: 1 1 3
#2: 1 3 3
#3: 2 5 9
#4: 2 9 9
#5: 3 4 4
#6: 3 NA 4
另一个选择是转换为符号,然后进行eval
求值
d[, paste0("max_", cn) := max(eval(as.symbol(cn)), na.rm = TRUE), by = a]