将列添加到R data.table并使用用户定义的函数进行聚合,将输出作为矢量返回

时间:2018-10-26 09:16:26

标签: r data.table

我不熟悉R中的data.table语法。

如何使用返回矢量的用户定义函数添加新列并进行汇总?

示例:

一些任意函数返回输入对象的均值和中位数。

myfunc<-function(x){ 
 vec<-c(rep(NA,2))
 vec[1]<-mean(x)
 vec[2]<-median(x)
 return(vec)
}

数据表

DT = data.table(
 ID = c("b","b","b","a","a","c"),
 a = 1:6,
 b = 7:12,
 c = 13:18
)

现在,我要总结一下,并获得一个尺寸为3x2的新数据表,即ID上为3行,a上使用的myfunc返回的均值和meadian为2列。

我尝试了(及其各种变化)

 DT[,c("avg","med")=myfunc(a),by=ID]

自然会失败。相反,我希望输出类似于

DT[, .(avg=mean(a),med=median(a)),by=ID]

> DT[, .(avg=mean(a),med=median(a)),by=ID]
#    ID avg med
# 1:  b 2.0 2.0
# 2:  a 4.5 4.5
# 3:  c 6.0 6.0

此外,我希望能得到一些解释,说明为什么我的荒谬尝试无法奏效,这样我以后就可以避免发布这样的愚蠢问题。

1 个答案:

答案 0 :(得分:0)

数据:

DT = data.table(
    ID = c("b","b","b","a","a","c"),
    a = 1:6,
    b = 7:12,
    c = 13:18
)

代码:

myfunc<-function(x){ 
    return( data.frame(avg = as.numeric(mean(x)), med = as.numeric(median(x))) )
}

# DT[,myfunc(.SD$a), by = ID] # can be simplified
DT[,myfunc(a), by = ID]  

结果:

#   ID avg med
#1:  b 2.0 2.0
#2:  a 4.5 4.5
#3:  c 6.0 6.0

扩展名:

DT[,do.call(cbind, lapply(.SD, myfunc)), by = ID]  # or
# DT[,unlist(lapply(.SD, myfunc), recursive = F), by = ID]


#   ID a.avg a.med b.avg b.med c.avg c.med
#1:  b   2.0   2.0   8.0   8.0  14.0  14.0
#2:  a   4.5   4.5  10.5  10.5  16.5  16.5
#3:  c   6.0   6.0  12.0  12.0  18.0  18.0