将聚合函数应用于具有自定义输出名称的多个 data.table 列

时间:2021-02-12 21:04:50

标签: r data.table

如果这是重复的,我们深表歉意。我对 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')]

有没有办法简洁地做到这一点?这是必要的,因为代码可能嵌入到一个函数中,并且可能需要处理无限数量的列。

2 个答案:

答案 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)

[ 中使用 .SDcolssetNames 的单个 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