通过许多列的飞行因子求和

时间:2016-09-19 22:57:58

标签: r data.table aggregate categories

我想按几列的切割值计算总和。 我知道如何为每个列手动执行此操作,但我正在努力寻找一种方法来自动化所有列的功能。通常我会用lapply来使用我的函数,但是我选择用data.table来做它,我无法弄清楚如何使用char值。

我希望有一个data.tables列表,其中包含每个类别的总和或者矩阵/ data.table,每个列变量的第一列和以下列作为类别,例如

data.table(col.name=c("v1","v2"), low=c( 1185.3074,1175.7261 ), high=c( 1175.726,350.3937 ))

MWE

rm(list=ls())
if(!require(data.table)) { install.packages("data.table"); require(data.table)}
set.seed(123)
DT<-data.table(v1=runif(50,10,50),v2=runif(50,10,50))

DT[,sum(v1, na.rm = T), by=cut(DT[,v1], breaks=c(0,25,50), labels = c("low", "high"))]
DT[,sum(v2, na.rm = T), by=cut(DT[,v2], breaks=c(0,25,50), labels = c("low", "high"))]

4 个答案:

答案 0 :(得分:3)

我想一种标准的方法是重塑两次:

dcast(
  melt(DT), 
  variable ~ cut(value, c(0,25,50), c("low","high")), 
  fun = sum
)

#    variable      low     high
# 1:       v1 323.2453 1216.937
# 2:       v2 331.0626 1122.991

melt重塑为&#34; long&#34 ;;而dcast恢复为&#34;宽。&#34;

答案 1 :(得分:1)

您可以尝试这样的事情,但不是您想要的但结果是接近的并且它会自动化汇总过程(实质上它仍然是循环遍历数据表的所有列并分别汇总每个列):

DT[, c(lapply(.SD, function(col) tapply(col, cut(col, breaks = c(0, 25, 50)), FUN=sum)), 
       list(category = c('low', 'high')))]

#          v1        v2 category
#1:  323.2453  331.0626      low
#2: 1216.9367 1122.9914     high

答案 2 :(得分:1)

基础R解决方案:

do.call(rbind, lapply(DT, function(x) tapply(x, cut(x, 0:2*25), sum)))

#        (0,25]     (25,50]
#v1 323.2452605 1216.936685
#v2 331.0626328 1122.991399

答案 3 :(得分:0)

我从数据表开始,但我认为tidyr和dplyr更适合我以后的目的。在保持对命名的控制的同时,似乎更容易总结使用多个函数。无论如何,对同一个问题有第二个解决方案总是好的,我需要轻推才能重塑我的数据。

if(!require(dplyr)) { install.packages("dplyr"); require(dplyr)}
if(!require(tidyr)) { install.packages("tidyr"); require(tidyr)}
DT %>% 
    gather(variable, value) %>%
    mutate(segment = cut(value, c(0,25,50), c("low","high"))) %>%
    group_by(variable,segment) %>%
    summarise(sum=sum(value)) %>%
    spread(segment, sum)