如果这是重复的,我们深表歉意。我对 data.table 很陌生,在这里看到过非常相似的问题,但没有一个能完全回答我的问题。
我想找到一种简洁的语法来聚合具有相同聚合函数的 data.table 的多列,以及生成的聚合列的自定义名称。
library(data.table)
data(mtcars)
setDT(mtcars)
如果我打电话
mtcars[, lapply(.SD, sum, na.rm = TRUE), by = .(am, gear), .SDcols = c('mpg','cyl')]
结果是
am gear mpg cyl
1: 1 4 210.2 36
2: 0 3 241.6 112
3: 0 4 84.2 20
4: 1 5 106.9 30
这很好,但我希望最后两列由我提前定义的自定义名称调用。
我可以用
达到预期的结果mtcars[, .(sum_of_mpg = sum(mpg, na.rm = TRUE), sum_of_cyl = sum(cyl, na.rm = TRUE)), by = .(am, gear)]
结果是
am gear sum_of_mpg sum_of_cyl
1: 1 4 210.2 36
2: 0 3 241.6 112
3: 0 4 84.2 20
4: 1 5 106.9 30
但是这个结果不能推广到允许我预先定义自定义名称。
我已经尝试了下面的代码和它的各种变体,但没有一步给出这个结果。
custom_names <- c('sum_of_mpg','sum_of_cyl')
mtcars[, (custom_names) = lapply(.SD, sum, na.rm = TRUE), by = .(am, gear), .SDcols = c('mpg','cyl')]
有没有办法简洁地做到这一点?这是必要的,因为代码可能嵌入到一个函数中,并且可能需要处理无限数量的列。
答案 0 :(得分:1)
这是一个可用的解决方案
in_names <- c('mpg','cyl')
custom_names <- c('sum_of_mpg','sum_of_cyl')
mtcars[, lapply(.SD, sum, na.rm = TRUE), by = .(am, gear), .SDcols = in_names][
,setnames(.SD,in_names,custom_names)][]
您可以尝试另一个稍微复杂的解决方案
mtcars[,as.list(unlist(lapply(.SD, function(x)
list(sum=sum(x))))),
by = .(am,gear),
.SDcols = in_names]
改进的解决方案
mtcars[, sapply(.SD, function(x) list(sum = sum(x))),
.SDcols = in_names,
by = .(am, gear)]
答案 1 :(得分:1)
在 [
中使用 .SDcols
和 setNames
的单个 lapply
调用:
cols <- c('mpg','cyl')
mtcars[, lapply(setNames(.SD, paste0("sum_of_", cols)), sum, na.rm = TRUE),
by = .(am, gear), .SDcols = cols]
# am gear sum_of_mpg sum_of_cyl
# <num> <num> <num> <num>
# 1: 1 4 210.2 36
# 2: 0 3 241.6 112
# 3: 0 4 84.2 20
# 4: 1 5 106.9 30