【问题标题】:Aggregate calculations with and without grouping variable in data.table在 data.table 中有和没有分组变量的聚合计算
【发布时间】:2015-09-10 17:55:56
【问题描述】:

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

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

到目前为止,我的解决方法是在摘要统计信息或原始数据副本上使用 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”值(在第一种方法中会导致两行@ 987654324@物种。)

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

【问题讨论】:

  • 第一种方式,如果使用c(list(Species="Overall"), lapply(.SD, median))则不需要填写
  • rbind 具有相同的 fill 参数 - 没有必要这样做尴尬的 rbindlist(list( 构造
  • @Frank 没错,你也不需要list

标签: r data.table


【解决方案1】:

我想我通常会这样做:

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

【讨论】:

  • 这个答案让我明白了两件事。首先提醒data.table::rbindrbindlist基本相同(至少现在是这样,?rbindlist在早期版本中并不清楚)。更重要的是,我正在创建一个副本以避免通过引用编辑d,但我可以添加一个辅助计算[, Species := ...]。非常感谢。
【解决方案2】:

我接受了@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 毫秒)。

【讨论】:

    猜你喜欢
    • 2020-03-26
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多