2013-06-01 69 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的评论我不知道是否有方法来改变函数返回的方式结果是为了改善这一点。 –

相关问题