2013-09-24 73 views
9

我想同樣的結果在R summarizing multiple columns with data.table而是幾彙總函數。R有關的多個列的多個統計與data.table

下面是一個例子

data <- as.data.table(list(x1 = runif(200), x2 = 10*runif(200), group = factor(sample(letters[1:2])))) 

res <- data[, rbindlist(lapply(.SD, function(x) { 
       return(list(name = "varname", mean = mean(x), sd = sd(x))) 
      })) 
      , by = group, .SDcols = c("x1", "x2") 
      ] 

,並得到以下結果:

group name  mean  sd 
1:  b varname 0.5755798 0.2723767 
2:  b varname 5.5108886 2.7649262 
3:  a varname 0.4906111 0.3060961 
4:  a varname 4.7780189 2.9740149 

我怎樣才能獲得在第二列的列名( 'X1', 'X2')?我想我需要用rbindlist替代別的東西,但是什麼?有沒有簡單的解決方案?

回答

13

另一種方法是構建自己的功能,這樣就可以避開這個rbindlist包(我覺得這是不必要的),讓你的自由構建你想要的功能:

tmp <- function(x) { 
    mm <- colMeans(x) 
    ss=sapply(x, sd) 
    list(names=names(x), mean=mm, sd=ss) 
} 

data[, tmp(.SD), by=group] 
    group names  mean  sd 
1:  a x1 0.4988514 0.2770122 
2:  b x1 0.5246786 0.3014248 
3:  a x2 4.8031253 2.7978401 
4:  b x2 4.9104108 2.9135656 
+0

+1這更加優雅。 – juba

4

您可以在names(.SD)而不是.SD上迭代lapply。事情是這樣的:

data <- as.data.table(list(x1 = runif(200), x2 = 10*runif(200), group = factor(sample(letters[1:2])))) 
res <- data[, rbindlist(lapply(names(.SD), function(name) { 
       return(list(name = name, mean = mean(.SD[[name]]), sd = sd(.SD[[name]]))) 
      })) 
      , by = group, .SDcols = c("x1", "x2")] 

其中給出:

group name  mean  sd 
1:  b x1 0.5344272 0.2697610 
2:  b x2 4.7628178 2.8313825 
3:  a x1 0.5008916 0.2686017 
4:  a x2 4.6175027 2.8942875