8

すべてに少なくとも1つの行が含まれ(実際には、1つの行のみが含まれるものもあれば、特定の数の行が含まれるものもある)、すべて同じ列(名前とタイプ)。重要な場合は、行のどこにもNAがないことも確信しています。

状況は次のようにシミュレートできます。

#create one row
onerowdfr<-do.call(data.frame, c(list(), rnorm(100) , lapply(sample(letters[1:2], 100, replace=TRUE), function(x){factor(x, levels=letters[1:2])})))
colnames(onerowdfr)<-c(paste("cnt", 1:100, sep=""), paste("cat", 1:100, sep=""))
#reuse it in a list
someParts<-lapply(rbinom(200, 1, 14/200)*6+1, function(reps){onerowdfr[rep(1, reps),]})

(ランダム化の)パラメーターを設定して、実際の状況に近づけるようにしました。

ここで、これらすべてのデータフレームを1つのデータフレームに統合したいと思います。rbindを使用すると、次のようにうまくいくと思いました。

system.time(
result<-do.call(rbind, someParts)
)

さて、私のシステム(特に遅くはありません)で、上記の設定で、これはsystem.timeの出力です:

   user  system elapsed 
   5.61    0.00    5.62

200個の変数の254行(私の場合)を処理するのに6秒近くかかりますか?確かに、ここでパフォーマンスを向上させる方法が必要ですか?私のコードでは、同様のことを頻繁に行う必要があるため(複数の代入によるものです)、これをできるだけ高速にする必要があります。

4

5 に答える 5

15

数値変数のみで行列を作成し、最後に因子に変換できますか? rbind数値行列でははるかに高速です。

私のシステムでは、データフレームを使用しています。

> system.time(result<-do.call(rbind, someParts))
   user  system elapsed 
  2.628   0.000   2.636 

代わりに、すべての数値行列を使用してリストを作成します。

onerowdfr2 <- matrix(as.numeric(onerowdfr), nrow=1)
someParts2<-lapply(rbinom(200, 1, 14/200)*6+1, 
                   function(reps){onerowdfr2[rep(1, reps),]})

結果ははるかに高速になりrbindます。

> system.time(result2<-do.call(rbind, someParts2))
   user  system elapsed 
  0.001   0.000   0.001

編集:ここに別の可能性があります。各列を順番に組み合わせるだけです。

> system.time({
+   n <- 1:ncol(someParts[[1]])
+   names(n) <- names(someParts[[1]])
+   result <- as.data.frame(lapply(n, function(i) 
+                           unlist(lapply(someParts, `[[`, i))))
+ })
   user  system elapsed 
  0.810   0.000   0.813  

ただし、マトリックスを使用するほど速くはありません。

編集2:

数値と係数しかない場合は、すべてを数値にrbind変換し、必要な列を係数に戻すのはそれほど難しくありません。これは、すべての要素がまったく同じレベルであることを前提としています。整数から係数への変換も数値からの変換よりも高速なので、最初に整数に強制します。

someParts2 <- lapply(someParts, function(x)
                     matrix(unlist(x), ncol=ncol(x)))
result<-as.data.frame(do.call(rbind, someParts2))
a <- someParts[[1]]
f <- which(sapply(a, class)=="factor")
for(i in f) {
  lev <- levels(a[[i]])
  result[[i]] <- factor(as.integer(result[[i]]), levels=seq_along(lev), labels=lev)
}

私のシステムのタイミングは次のとおりです。

   user  system elapsed 
   0.090    0.00    0.091 
于 2011-05-12T15:40:11.090 に答える
5

大きな後押しではありませんが、パッケージから交換rbindすると、実行時間が約10%オフになります(私のマシンのサンプルデータセットを使用)。rbind.fillplyr

于 2011-05-12T16:38:38.460 に答える
4

本当に速く操作したい場合はdata.frame、パッケージdata.tableと関数を使用することをお勧めしますrbindlist()。広範なテストは実行しませんでしたが、データセット(3000データフレーム、1000行x 40列)のrbindlist()場合、20秒しかかかりません。

于 2013-07-10T11:35:43.347 に答える
3

これは約25%高速ですが、もっと良い方法が必要です...

system.time({
  N <- do.call(sum, lapply(someParts, nrow))
  SP <- as.data.frame(lapply(someParts[[1]], function(x) rep(x,N)))
  k <- 0
  for(i in 1:length(someParts)) {
    j <- k+1
    k <- k + nrow(someParts[[i]])
    SP[j:k,] <- someParts[[i]]
  }
})
于 2011-05-12T17:00:28.977 に答える
1

データフレームをデータフレームにバインドしていることを確認してください。リストをデータフレームにバインドするときに、パフォーマンスが大幅に低下しました。

于 2016-06-24T18:05:06.350 に答える