2013-06-01 68 views
4

這個問題是相似但不完全相同Add multiple columns to R data.table in one function call?如何從生成一​​個列表功能多列結果

比方說,我有一個data.table

ex<-data.table(AAA=runif(100000),BBBB=runif(100000),CCC=runif(100000),DDD=runif(100000),EEE=runif(100000),FFF=runif(100000),HHH=runif(100000),III=runif(100000),FLAG=c(rep(c("a","b","c","d","e"),200000))) 

我能得到的總和,平均通過做

ex[,c(sum=lapply(.SD,sum),mean=lapply(.SD,mean)),by=FLAG] 

所有列的結果好看我在附加到現有的列名,便於識別與外核層殲指定的名稱如預期的那樣,對於FLAG的每個值,y 1行。

但是,讓我們說我有一個返回值作爲

sk<-function(x){ 
    meanx<-mean(x) 
    lenx<-length(x) 
    difxmean<-x-meanx 
    m4<-sum((difxmean)^4)/lenx 
    m3<-sum((difxmean)^3)/lenx 
    m2<-sum((difxmean)^2)/lenx 
    list(mean=meanx,len=lenx,sd=m2^.5,skew=m3/m2^(3/2),kurt=(m4/m2^2)-3) 
} 

這樣一個列表功能。如果我做

ex[,lapply(.SD,sk),by=FLAG] 

我得到一排列表中的每個輸出結果。我想仍然只有一行結果與列的每個原始列和功能結果。

例如輸出列應

AAA.mean AAA.len  AAA.sd  AAA.skew AAA.kurt  BBBB.mean BBBB.len  BBBB.sd  BBBB.skew BBBB.kurt .... III.mean III.len  III.sd  III.skew III.kurt 

有沒有辦法做到這一點?

我知道我可以只是把在J所有這些單獨的功能,並獲得列,但我發現,當我使用這個功能,而不是單獨的功能對所有的時刻它是一個很好的快一點。

x<-runif(10000000) 
system.time({ 
mean(x) 
length(x) 
sd(x) 
skewness(x) 
kurtosis(x) 
}) 
user system elapsed 
5.84 0.47 6.30 

system.time(sk(x)) 
user system elapsed 
3.9  0.1  4.0 

回答

5

試試這個:

ex[, as.list(unlist(lapply(.SD, sk))), by = FLAG] 
+0

+1。我不知道是否有避免強迫以列表的方式([推薦](http://rwiki.sciviews.org/doku.php?id=packages:cran:data.table#don_t_coerce_j_to_list_use_list_directly))。 'do.call(「c」,...''和'Reduce(「c」,...'似乎也一樣慢) – Frank

+0

@Frank,'do.call(「c」,...)似乎沒問題,但是'Reduce(「c」,...)'失去了名字中重要部分的缺陷 –

+0

這是行不通的,但基於@ Frank的評論我不知道是否有方法來改變函數返回的方式結果是爲了改善這一點。 –

相關問題