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]

J で指定した名前を既存の列名に追加すると、結果は見栄えがよくなり、FLAG予想どおり、 の値ごとに 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]

リストの各出力の行で結果を取得します。元の列と関数の結果のそれぞれの列を含む結果を 1 行だけ残したいと思います。

たとえば、出力列は次のようになります。

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 
4

1 に答える 1

5

これを試して:

ex[, as.list(unlist(lapply(.SD, sk))), by = FLAG]
于 2013-06-01T15:11:11.640 に答える