【问题标题】:Summarizing multiple columns with data.table用 data.table 汇总多列
【发布时间】:2013-05-07 00:02:06
【问题描述】:

我正在尝试使用 data.table 来加快处理由几个较小的合并 data.frames 组成的大型 data.frame (300k x 60)。我是 data.table 的新手。到目前为止的代码如下

library(data.table)
a = data.table(index=1:5,a=rnorm(5,10),b=rnorm(5,10),z=rnorm(5,10))
b = data.table(index=6:10,a=rnorm(5,10),b=rnorm(5,10),c=rnorm(5,10),d=rnorm(5,10))
dt = merge(a,b,by=intersect(names(a),names(b)),all=T)
dt$category = sample(letters[1:3],10,replace=T)

我想知道是否有比以下更有效的方法来汇总数据。

summ = dt[i=T,j=list(a=sum(a,na.rm=T),b=sum(b,na.rm=T),c=sum(c,na.rm=T),
                     d=sum(d,na.rm=T),z=sum(z,na.rm=T)),by=category]

我真的不想手动输入所有 50 列计算,eval(paste(...)) 似乎有点笨拙。

我查看了下面的示例,但对于我的需求来说似乎有点复杂。谢谢

how to summarize a data.table across multiple columns

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您可以使用简单的lapply 语句和.SD

    dt[, lapply(.SD, sum, na.rm=TRUE), by=category ]
    
       category index        a        b        z         c        d
    1:        c    19 51.13289 48.49994 42.50884  9.535588 11.53253
    2:        b     9 17.34860 20.35022 10.32514 11.764105 10.53127
    3:        a    27 25.91616 31.12624  0.00000 29.197343 31.71285
    

    如果您只想对某些列进行汇总,可以添加 .SDcols 参数

    #  note that .SDcols also allows reordering of the columns
    dt[, lapply(.SD, sum, na.rm=TRUE), by=category, .SDcols=c("a", "c", "z") ] 
    
       category        a         c        z
    1:        c 51.13289  9.535588 42.50884
    2:        b 17.34860 11.764105 10.32514
    3:        a 25.91616 29.197343  0.00000
    

    这当然不限于sum,您可以使用lapply 的任何函数,包括匿名函数。 (即,这是一个常规的lapply 声明)。

    最后,没有必要使用i=Tj= <..>。就个人而言,我认为这会降低代码的可读性,但这只是一种风格偏好。


    文档

    请参阅 ?.SD?data.table 及其 .SDcols 参数,以及小插图 Using .SD for Data Analysis

    也可以看看data.tableFAQ 2.1

    【讨论】:

    • 如果你想要不同列的多个聚合函数怎么办?例如,您想要 a 列的总和和 b 列的平均值
    • 回答我的问题:DT[, .(agra = sum(a), agrb = mean(b)), by=category]
    • 有没有办法在 lapply 中自动使列名“sum a”、“sum b”、“sum c”?
    • 现在有与使用 .SD 不同的方法吗?
    • @Mark 你可以这样使用 data.table::setattr dt[, { lapply(.SD, sum, na.rm=TRUE) %>% setattr(., "names" , value = sprintf("sum_%s", names(.))) }, by=category, .SDcols=c("a", "c", "z") ]
    猜你喜欢
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 2016-07-31
    • 2020-11-27
    • 2019-03-19
    • 1970-01-01
    相关资源
    最近更新 更多