假定以下虚拟数据帧:
dt <- data.table(A=c("a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d", "d"),
B=c("e", "e", "e", "e", "e", "e", "f", "f", "f", "f", "f", "f"),
C=1:12,
D=13:24)
我想计算每个数字列(“ C”和“ D”)以及每次按因子列c(“ A”),c(”分组的时间的一些统计量(例如,均值和标准差) B“)和c(” A“,” B)。在实际的数据框中,我大约有40个数字列,10个因子列,它们以不同的组合进行分组,并且我想计算大量的统计信息。 基于我从上一个问题中得到的answer(通过@thelatemail),我知道我可以使用以下代码使用列表来处理因子分组(by =):
groupList <- list(c("A", "B"), c("A"), c("B"))
out <- vector("list", 3)
out <- lapply(
groupList,
function(x) {
dt[, .(mean=mean(C), sd=sd(C)), by=x]
}
)
现在,我想更进一步,创建一个包含数据框中数字列名称列表的变量,并在上面的函数中使用该变量的名称。我给出了以下代码,但不幸的是,它不起作用。我的想法是在每次旋转时使用循环从measureList提取值,并将该值放置在均值sd函数中。有任何想法吗?循环是我倾向于想到这些事情的方式,但是如果它使代码更快或更高效(特别是因为我拥有的一个因素列具有90个级别),我将很高兴摆脱它。我将不胜感激任何指针来解决这个问题!谢谢。
factorList <- list(c("A"), c("B"), c("A", "B"))
measureList <- list(c("C"), c("D"))
out <- vector("list", 2)
for(i in 1:length(measureList)){
out[[i]] <-lapply(
factorList,
function(x) {
dt[, .(mean=mean(eval(measureList[[i]])),
sd=sd(eval(measureList[[i]]))),
by = x]
}
)
}
答案 0 :(得分:2)
另一种可能性是使用data.table中新的groupingsets
函数:
groupingsets(dt
, j = lapply(.SD, function(x) list(mean(x), sd(x)))
, by = c('A','B')
, sets = factorList)[, type := c('mean','sd')][]
给出:
A B C D type 1: a <NA> 2 14 mean 2: a <NA> 1 1 sd 3: b <NA> 5 17 mean 4: b <NA> 1 1 sd 5: c <NA> 8 20 mean 6: c <NA> 1 1 sd 7: d <NA> 11 23 mean 8: d <NA> 1 1 sd 9: <NA> e 3.5 15.5 mean 10: <NA> e 1.870829 1.870829 sd 11: <NA> f 9.5 21.5 mean 12: <NA> f 1.870829 1.870829 sd 13: a e 2 14 mean 14: a e 1 1 sd 15: b e 5 17 mean 16: b e 1 1 sd 17: c f 8 20 mean 18: c f 1 1 sd 19: d f 11 23 mean 20: d f 1 1 sd
答案 1 :(得分:1)
这使用了dplyr
和purrr
,但我认为它是可行的。
library(dplyr)
library(purrr)
combos <- expand.grid(factorList, measureList)
map2(combos[, 1],
combos[, 2],
~ dt %>% group_by_at(.x) %>% summarize_at(.y, funs(mean, sd)))
答案 2 :(得分:1)
您可以将outer
与矢量化功能一起使用,也可以如下使用Map
:
m = function(x,y)dt[, .(mean=mean(get(y)), sd=sd(get(y))), by=x]
c(outer(factorList,measureList,Vectorize(m)))
或
Map(m,rep(factorList,each=length(measureList)),measureList)
编辑:
拥有名字:
m = function(x,y)setNames(dt[, .(mean(get(y)),sd(get(y))), by=x],
c(head(names(dt),length(x)),paste(c("mean","sd"),y,sep="_")))
c(outer(factorList,measureList,Vectorize(m)))