在 data.table 中使用和不使用分组变量的聚合计算

Aggregate calculations with and without grouping variable in data.table

我正在按组和总体级别生成一些汇总统计数据。

(注意:总体统计数据不一定来自组级统计数据。加权平均值可以,但中位数不行。)

到目前为止,我的解决方法是对摘要统计信息或原始数据的副本使用 rbindlist,如:

library(data.table)
data(iris)

d <- data.table(iris)

# Approach 1)

rbindlist(list(d[, lapply(.SD, median),  by=Species, .SDcols=c('Sepal.Length','Petal.Length')],
               d[, lapply(.SD, median),  .SDcols=c('Sepal.Length', 'Petal.Length')]),
      fill=TRUE)
#       Species Sepal.Length Petal.Length
# 1:     setosa          5.0         1.50
# 2: versicolor          5.9         4.35
# 3:  virginica          6.5         5.55
# 4:         NA          5.8         4.35

# Approach 2)

d2 <- rbindlist(list(copy(d), copy(d[,Species:="Overall"]) ) )
d2[, lapply(.SD, median),  by=Species, .SDcols=c('Sepal.Length', 'Petal.Length')]
#       Species Sepal.Length Petal.Length
# 1:     setosa          5.0         1.50
# 2: versicolor          5.9         4.35
# 3:  virginica          6.5         5.55
# 4:    Overall          5.8         4.35

第一种方法似乎更快(避免复制)。

第二种方法允许我使用标签 "Overall" 而不是 NA 填充,如果某些记录缺少 "Species" 值(在第一个方法将导致两行 NA 物种。)

我应该考虑其他解决方案吗?

我想我通常是这样做的:

cols = c('Sepal.Length','Petal.Length')

rbind(d[, lapply(.SD, median), by=Species, .SDcols=cols],
      d[, lapply(.SD, median), .SDcols=cols][, Species := 'Overall'])
#      Species Sepal.Length Petal.Length
#1:     setosa          5.0         1.50
#2: versicolor          5.9         4.35
#3:  virginica          6.5         5.55
#4:    Overall          5.8         4.35

我接受了@Eddi 的回答,但想采纳@Frank 的好评。这种方法 IMO 最有意义。

library(data.table)
d <- data.table(iris)
cols = c('Sepal.Length','Petal.Length')

rbind(d[, lapply(.SD, median), by=Species, .SDcols=cols],
      d[, c(Species = 'Overall', lapply(.SD, median) ), .SDcols=cols])
#       Species Sepal.Length Petal.Length
# 1:     setosa          5.0         1.50
# 2: versicolor          5.9         4.35
# 3:  virginica          6.5         5.55
# 4:    Overall          5.8         4.35

它也可能比应用二次计算稍快(microbenchmark 上为 1.54 与 1.73 毫秒)。