我不熟悉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
此外,我希望能得到一些解释,说明为什么我的荒谬尝试无法奏效,这样我以后就可以避免发布这样的愚蠢问题。
答案 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