我正在努力使用data.table来总结矢量函数的结果,这在ddply中很容易。
问题1:使用矢量输出聚合(昂贵)函数
dt <- data.table(x=1:20,y=rep(c("a","b"),each=10))
这个ddply命令可以产生我想要的东西:
ddply(dt,~y,function(dtbit) quantile(dtbit$x))
此数据表命令无法执行我想要的操作:
dt[,quantile(x),by=list(y)]
我可以像这样破解data.table:
dt[,list("0%"=quantile(x,0),"25%"=quantile(x,0.25),
"50%"=quantile(x,0.5)),by=list(y)]
但是那个冗长,如果矢量函数“分位数”很慢,也会很慢。
类似的例子是:
dt$z <- rep(sqrt(1:10),2)
ddply(dt,~y,function(dtbit) coef(lm(z~x,dtbit)))
问题2:使用带矢量输入和输出的函数
xzsummary <- function(dtbit) t(summary(dtbit[,"x"]-dtbit[,"z"]))
ddply(dt,~y,xzsummary )
我可以在data.table中轻松完成这类工作吗?
如果这些问题已得到明确回答,请道歉。
这是一个类似的,不完全相同的问题: data.table aggregations that return vectors, such as scale()
答案 0 :(得分:7)
> dt[ , as.list(quantile(x)),by=y]
y 0% 25% 50% 75% 100%
1: a 1 3.25 5.5 7.75 10
2: b 11 13.25 15.5 17.75 20
我尝试使用rbind
,但未能产生我认为你想要的by-y安排。 as.list
(vs. list
)的技巧是它构造了一个多元素列表wehn givne一个向量,而list
只将向量放入一个元素列表。
as.list
的行为类似于sapply(x, list)
:
> dt[ , sapply(quantile(x), list), by=y]
y 0% 25% 50% 75% 100%
1: a 1 3.25 5.5 7.75 10
2: b 11 13.25 15.5 17.75 20
您的目标解决方案:
> ddply(dt,~y,function(dtbit) quantile(dtbit$x))
y 0% 25% 50% 75% 100%
1 a 1 3.25 5.5 7.75 10
2 b 11 13.25 15.5 17.75 20
我为这个解决方案感到自豪,但注意fortunes::fortune("Liaw-Baron principle")
............
最后,通过我们所谓的“Liaw-Baron原则”,可以提出的每一个问题实际上都是 已被问过。 - Dirk Eddelbuettel(引用Andy Liaw和Jonathan Baron关于R-help的独特问题的意见) R-help(2006年1月)
....我搜索了[r] data.table as.list
,并发现我绝不是第一个在SO上发布此策略的人:
Using ave() with function which returns a vector
create a formula in a data.table environment in R
我真的不知道这个问题是否会被视为重复,但我特别感谢@ G.Grothedieck的最后一个。这可能是我选择策略的地方。那次搜索大约有125次点击,我只是通过前20次搜集这些例子,所以可能还有一些我没有发现的珍珠。