4

より多くの RAM を搭載したマシンで作業する以外に、 で大きなリストを操作するにはどうすればよいRですか。

私が使用しているタイプのリストを生成するためのコードを次に示します

n = 50; i = 100
WORD <- vector(mode = "integer", length = n)
for (i in 1:n){
  WORD[i] <- paste(sample(c(rep(0:9,each=5),LETTERS,letters),5,replace=TRUE),collapse='')
}
dat <- data.frame(WORD =  WORD,
                  COUNTS = sample(1:50, n, replace = TRUE))
dat_list <- lapply(1:i, function(i) dat) 

私の実際の使用例では、ここでの簡単な例とは異なり、リスト内の各データ フレームは一意です。n=4000、i=100,000を目指しています

これは、このデータフレームのリストでやりたいことの一例です。

FUNC <- function(x) {rep(x$WORD, times = x$COUNTS)}
la <- lapply(dat_list, FUNC)

私の実際の使用例では、これは数時間実行され、RAM とほとんどのスワップがいっぱいになり、その後 RStudio がフリーズして爆弾を含むメッセージが表示されます (R セッションでエラーが発生したため、RStudio は強制的に終了されました)。

これはbigmemory行列に限定されており、ffリストを処理していないようです。他のオプションは何ですか?sqldfここで、または関連するメモリ不足の方法が可能な場合、どうすれば始められますか? ドキュメントから十分な情報を得ることができず、進歩を遂げることができず、ポインタがあれば感謝しています。「RAM を追加購入する」という指示は無視されることに注意してください。これは、平均的なデスクトップ コンピューター (学部生のコンピューター ラボ) に適していると期待しているパッケージ用です。

更新SimonO101 と Ari からの有益なコメントをフォローアップして、dataframe と data.tables、loops と lapply、gc の有無を比較したベンチマークをいくつか示します。

# self-contained speed test of untable
n = 50; i = 100
WORD <- vector(mode = "integer", length = n)
for (i in 1:n){
  WORD[i] <- paste(sample(c(rep(0:9,each=5),LETTERS,letters),5,replace=TRUE),collapse='')
}
# as data table
library(data.table)
dat_dt <- data.table(WORD = WORD, COUNTS = sample(1:50, n, replace = TRUE))
dat_list_dt <- lapply(1:i, function(i) dat_dt)

# as data frame
dat_df <- data.frame(WORD =  WORD, COUNTS = sample(1:50, n, replace = TRUE))
dat_list_df <- lapply(1:i, function(i) dat_df)

# increase object size
y <- 10
dt <- c(rep(dat_list_dt, y))
df <- c(rep(dat_list_df, y))
# untable
untable <- function(x) rep(x$WORD, times = x$COUNTS)


# preallocate objects for loop to fill
df1 <- vector("list", length = length(df))
dt1 <- vector("list", length = length(dt))
df3 <- vector("list", length = length(df))
dt3 <- vector("list", length = length(dt))
# functions for lapply
df_untable_gc <- function(x) { untable(df[[x]]); if (x%%10) invisible(gc()) }
dt_untable_gc <- function(x) { untable(dt[[x]]); if (x%%10) invisible(gc()) }
# speedtests
library(microbenchmark)
microbenchmark(
  for(i in 1:length(df)) { df1[[i]] <- untable(df[[i]]); if (i%%10) invisible(gc()) },
  for(i in 1:length(dt)) { dt1[[i]] <- untable(dt[[i]]); if (i%%10) invisible(gc()) },
  df2 <- lapply(1:length(df), function(i) df_untable_gc(i)),
  dt2 <- lapply(1:length(dt), function(i) dt_untable_gc(i)),
  for(i in 1:length(df)) { df3[[i]] <- untable(df[[i]])},
  for(i in 1:length(dt)) { dt3[[i]] <- untable(dt[[i]])},
  df4 <- lapply(1:length(df), function(i) untable(df[[i]]) ),
  dt4 <- lapply(1:length(dt), function(i) untable(dt[[i]]) ),

  times = 10)

そして、これが結果です。明示的なガベージ コレクションを使用しない場合、data.table はループよりもはるかに高速で、lapply はわずかに高速です。明示的なガベージ コレクションを使用すると (SimonO101 が示唆していると思われるように)、それらはすべてほぼ同じ速度であり、はるかに遅くなります! usinggcは少し議論の余地があり、この場合はおそらく役に立たないことはわかっていますが、実際のユースケースで試してみて、違いがあるかどうかを確認します. もちろん、これらの関数のメモリ使用に関するデータはありません。これが私の主な関心事です。タイミング機能に相当するメモリベンチマーク用の機能がないようです(とにかくWindows用)。

Unit: milliseconds
                                                                                                 expr
 for (i in 1:length(df)) {     df1[[i]] <- untable(df[[i]])     if (i%%10)          invisible(gc()) }
 for (i in 1:length(dt)) {     dt1[[i]] <- untable(dt[[i]])     if (i%%10)          invisible(gc()) }
                                            df2 <- lapply(1:length(df), function(i) df_untable_gc(i))
                                            dt2 <- lapply(1:length(dt), function(i) dt_untable_gc(i))
                                         for (i in 1:length(df)) {     df3[[i]] <- untable(df[[i]]) }
                                         for (i in 1:length(dt)) {     dt3[[i]] <- untable(dt[[i]]) }
                                            df4 <- lapply(1:length(df), function(i) untable(df[[i]]))
                                            dt4 <- lapply(1:length(dt), function(i) untable(dt[[i]]))
          min           lq       median           uq         max neval
 37436.433962 37955.714144 38663.120340 39142.350799 39651.88118    10
 37354.456809 38493.268121 38636.424561 38914.726388 39111.20439    10
 36959.630896 37924.878498 38314.428435 38636.894810 39537.31465    10
 36917.765453 37735.186358 38106.134494 38563.217919 38751.71627    10
    28.200943    29.221901    30.205502    31.616041    34.32218    10
    10.230519    10.418947    10.665668    12.194847    14.58611    10
    26.058039    27.103217    27.560739    28.189448    30.62751    10
     8.835168     8.904956     9.214692     9.485018    12.93788    10
4

1 に答える 1