从返回多个输出的函数创建聚合输出data.table [英] Create aggregate output data.table from function returning multiple output

查看:46
本文介绍了从返回多个输出的函数创建聚合输出data.table的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力解决我有的一个特定问题,我搜索了stackoverflow,找到了接近但不完全是我想要的示例。 最接近的示例是here

此帖子(here)也很接近,但我无法使我的多输出函数与List()一起使用

我要做的是创建包含聚合值(MIN、MAX、Mean、MyFunc)并按键分组的表。 我还有一些返回多个输出的复杂函数。我可以返回单个输出,但这意味着要多次运行复杂的函数,并且会花费太长时间。

使用this post中的Matt Dowle示例,并做了一些更改

x <- data.table(a=1:3,b=1:6)[]
   a b
1: 1 1
2: 2 2
3: 3 3
4: 1 4
5: 2 5
6: 3 6

这是我想要的输出类型。聚合表(此处仅包含平均值和总和)

agg.dt <- x[ , list(mean=mean(b), sum=sum(b)), by=a][]
   a mean sum
1: 1  2.5   5
2: 2  3.5   7
3: 3  4.5   9
此示例函数f返回3个输出。我真正的功能要复杂得多,成分不能这样拆分。

f <- function(x) {list(length(x), min(x), max(x))}

Matt Dowle在上一篇文章中的建议效果很好,但没有生成和聚合表,而是将聚合添加到主表中(这在其他情况下也非常有用)

x[, c("length","min", "max"):= f(b), by=a][]
   a b length min max
1: 1 1      2   1   4
2: 2 2      2   2   5
3: 3 3      2   3   6
4: 1 4      2   1   4
5: 2 5      2   2   5
6: 3 6      2   3   6
我真正想做的(如果可能的话)是…

agg.dt <- x[ , list(mean=mean(b)
                       , sum=sum(b)
                       , c("length","min", "max") = f(b)
), by=a]
并返回一个聚合表,如下所示的…

     a mean sum length min max
1: 1  2.5   5           2   1   4
2: 2  3.5   7           2   2   5
3: 3  4.5   9           2   3   6

我只能真正看到这样一种解决方案,即这是一个两阶段流程并将表合并/联接在一起?

推荐答案

library(data.table)
x <- data.table(a=1:3,b=1:6)
#have the function return a named list
f <- function(x) {list(length=length(x), 
                       min=min(x), 
                       max=max(x))}

# c can combine lists
# c(vector, vector, 3-list) is a 5-list
agg.dt <- x[ , c(mean=mean(b),
                 sum=sum(b),
                 f(b)), 
            by=a]

#   a mean sum length min max
#1: 1  2.5   5      2   1   4
#2: 2  3.5   7      2   2   5
#3: 3  4.5   9      2   3   6

或者,从f()中删除名称,以节省为每个组创建相同名称的时间和成本:

f <- function(x) {list(length(x), 
                       min(x), 
                       max(x))}

agg.dt <- x[ , c(mean(b),
                 sum(b),
                 f(b)),
            by=a]

setnames(agg.dt, c("a", "mean","sum","length", "min", "max"))

这个删除名称并将它们放回后面的技巧(当您有很多组时,为了提高速度)不会到达f()内部。f()可能返回任何内容,因此data.table更难自动优化。

还需要指出的是,从R3.1开始,base::list()不再复制命名输入。因此,函数f()执行一些复杂步骤,然后在末尾返回list()局部变量的常见R习惯用法现在应该会更快。

这篇关于从返回多个输出的函数创建聚合输出data.table的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆