2014-02-20 33 views
2

我使用data.table的by參數創建了很多列。以下是我將用來說明問題的一些示例數據。如何使用data.table'by'參數來創建多列數據?

> dt <- data.table(x=runif(10), group=c(1,1,1,1,1,2,2,2,2,2)) 
> dt 
      x group 
1: 0.0488727  1 
2: 0.3087102  1 
3: 0.8107115  1 
4: 0.7368206  1 
5: 0.2941478  1 
6: 0.5221693  2 
7: 0.2505612  2 
8: 0.2730681  2 
9: 0.2098595  2 
10: 0.4512163  2 

我想使用「by」參數爲每組數據做一些彙總統計。一種選擇是他們都在dt分配給列:

> dt[, max:=max(x), by=group] 
> dt[, min:=min(x), by=group] 
> dt[, mean:=mean(x), by=group] 
> dt[, median:=median(x), by=group] 
> dt 
      x group  max  min  mean median 
1: 0.0488727  1 0.8107115 0.0488727 0.4398526 0.3087102 
2: 0.3087102  1 0.8107115 0.0488727 0.4398526 0.3087102 
3: 0.8107115  1 0.8107115 0.0488727 0.4398526 0.3087102 
4: 0.7368206  1 0.8107115 0.0488727 0.4398526 0.3087102 
5: 0.2941478  1 0.8107115 0.0488727 0.4398526 0.3087102 
6: 0.5221693  2 0.5221693 0.2098595 0.3413749 0.2730681 
7: 0.2505612  2 0.5221693 0.2098595 0.3413749 0.2730681 
8: 0.2730681  2 0.5221693 0.2098595 0.3413749 0.2730681 
9: 0.2098595  2 0.5221693 0.2098595 0.3413749 0.2730681 
10: 0.4512163  2 0.5221693 0.2098595 0.3413749 0.2730681 

,因爲你有很多不必要的重複元素創建列,這是不好的。我不知道合理的方式來摺疊data.table。

另一種方法是把每個結果到一個單獨的data.table,然後把它們合併起來:

> a<-dt[, max(x), by=group] 
> b<-dt[, min(x), by=group] 
> c<-dt[, mean(x), by=group] 
> d<-dt[, median(x), by=group] 
> setnames(a, "V1", "max") 
> setnames(b, "V1", "min") 
> setnames(c, "V1", "mean") 
> setnames(d, "V1", "median") 
> setkeyv(a, "group") 
> setkeyv(b, "group") 
> setkeyv(c, "group") 
> setkeyv(d, "group") 
> dt.summary.stats -> a[b][c][d] 
> dt.summary.stats 
    group  max  min  mean median 
1:  1 0.8107115 0.0488727 0.4398526 0.3087102 
2:  2 0.5221693 0.2098595 0.3413749 0.2730681 

dt.summary.stats包含了我想要的結果,但這種感覺就像一個非常愚蠢的辦法到達那裏。什麼是正確的方法來做到這一點?

+0

您可以在plyr包ddply嘗試。 ddply(dt,。(group),summary,max = max(x),min = min(x),mean = mean(x),median = median(x)) – Bangyou

+0

有點類似:http://stackoverflow.com /問題/ 16342261 /創建-A-表爲正最小 - 最大-SD-均值和中值在-R/16342881#16342881 – Frank

回答

7

在這裏你去:

dt[, list(max = max(x), min = min(x), mean = mean(x), median = median(x)), 
    by = group] 
# group  max  min  mean median 
#1:  1 0.8185661 0.02120035 0.3277341 0.1721039 
#2:  2 0.9243562 0.28941571 0.6137555 0.5826848 

或者只是使用summary

dt[, as.list(summary(x)), by = group] 
# group Min. 1st Qu. Median Mean 3rd Qu. Max. 
#1:  1 0.0212 0.1517 0.1721 0.3277 0.4751 0.8186 
#2:  2 0.2894 0.4243 0.5827 0.6138 0.8480 0.9244 
0

如何

aggregate(dt$x, by=list(dt$group), summary)

1

這應做到:

> dt[, list(max = max(x), min = min(x), mean = mean(x), median = median(x)), by = group] 
    group  max   min  mean median 
1:  1 0.9287178 0.337082563 0.6513641 0.6619631 
2:  2 0.6329924 0.001502332 0.4282116 0.4998901 
3

這裏有一個方法,可以讓你隨心所欲的使用匯總函數

summary_fun <- function(.fun,.x,...) { 
    .FUN = match.fun(.fun) 
    r <- .FUN(.x,...) 
} 


summary_list <- function(funs,.x,...){ 
    r <- lapply(funs, summary_fun,.x=.x,...) 
    setattr(r,'names',funs) 
} 


dt[,summary_list(c('mean','median','min','max'),.x=x,na.rm=TRUE),by=group] 
# group mean median  min max 
# 1  1 0.5128 0.5417 0.05253 0.8978 
# 2  2 0.5721 0.5828 0.3817 0.7549 
相關問題