2

この再形成をより速く、より少ないメモリで行うにはどうすればよいですか? 私の目的は、4 Gb RAM で 500,000 行 x 500 列のデータフレームを再形成することです。

再現可能なデータを作成する関数は次のとおりです。

make_example <- function(ndoc, ntop){
# doc numbers
V1 = seq(1:ndoc)
# filenames
V2 <- list("vector", size = ndoc)
for (i in 1:ndoc){
V2[i] <- paste(sample(c(rep(0:9,each=5),LETTERS,letters),5,replace=TRUE),collapse='')
}
# topic proportions
tvals <- data.frame(matrix(runif(1:(ndoc*ntop)), ncol = ntop))
# topic number
tnumvals <- data.frame(matrix(sample(1:ntop, size = ndoc*ntop, replace = TRUE), ncol = ntop))
# now make topic props and topic numbers alternating columns (rather slow!)
alternating <- data.frame(c(matrix(c(tnumvals, tvals), 2, byrow = T)) )
# make colnames for topic number and topic props
ntopx <- sapply(1:ntop, function(j) paste0("ntop_",j))
ptopx <- sapply(1:ntop, function(j) paste0("ptop_",j))
tops <- c(rbind(ntopx,ptopx)) 
# make data frame
dat <- data.frame(V1 = V1,
                 V2 =  unlist(V2), 
                 alternating)
names(dat) <- c("docnum", "filename", tops)
# give df as result
return(dat)
}

再現可能なデータを作成します。

set.seed(007)
dat <- make_example(500000, 500)

これが私の現在の方法です(https://stackoverflow.com/a/8058714/1036500に感謝します):

library(reshape2)
NTOPICS = (ncol(dat) - 2 )/2
nam <- c('num', 'text', paste(c('topic', 'proportion'), rep(1:NTOPICS, each = 2), sep = ""))

system.time( dat_l2 <- reshape(setNames(dat, nam), varying = 3:length(nam), direction = 'long', sep = ""))
system.time( dat.final2 <- dcast(dat_l2, dat_l2[,2] ~ dat_l2[,3], value.var = "proportion" ) )

いくつかのタイミングは、reshapeそれが最も遅いステップであるためです。

make_example(5000,100) = 82 秒

make_example(50000,200)= 2855 秒 (2 番目のステップでクラッシュ)

make_example(500000,500) = まだできません...

この reshape ( data.tablethis ) に対して、より高速でメモリの消費量が少ない他の方法はありますか?

4

1 に答える 1

2

500000 x 500 データフレームを渡すときに、これが少量の RAM で成功するかどうかは非常に疑わしいです。その限られたスペースで簡単な動作もできるかどうか。追加の RAM を購入します。さらに、reshape2 は遅いので、大きなものには stats::reshape を使用してください。そして、セパレーターが何であるかについてのヒントを与えます。

> set.seed(007)
> dat <- make_example(5, 3)
> dat
  docnum filename ntop_1     ptop_1 ntop_2    ptop_2 ntop_3    ptop_3
1      1    y8214      3 0.06564574      1 0.6799935      2 0.8470244
2      2    e6x39      2 0.62703876      1 0.2637199      3 0.4980761
3      3    34c19      3 0.49047504      3 0.1857143      3 0.7905856
4      4    1H0y6      2 0.97102441      3 0.1851432      2 0.8384639
5      5    P6zqy      3 0.36222085      3 0.3792967      3 0.4569039

> reshape(dat, direction="long", varying=3:8, sep="_")
    docnum filename time ntop       ptop id
1.1      1    y8214    1    3 0.06564574  1
2.1      2    e6x39    1    2 0.62703876  2
3.1      3    34c19    1    3 0.49047504  3
4.1      4    1H0y6    1    2 0.97102441  4
5.1      5    P6zqy    1    3 0.36222085  5
1.2      1    y8214    2    1 0.67999346  1
2.2      2    e6x39    2    1 0.26371993  2
3.2      3    34c19    2    3 0.18571426  3
4.2      4    1H0y6    2    3 0.18514322  4
5.2      5    P6zqy    2    3 0.37929675  5
1.3      1    y8214    3    2 0.84702439  1
2.3      2    e6x39    3    3 0.49807613  2
3.3      3    34c19    3    3 0.79058557  3
4.3      4    1H0y6    3    2 0.83846387  4
5.3      5    P6zqy    3    3 0.45690386  5

> system.time( dat <- make_example(5000,100) )
   user  system elapsed 
  2.925   0.131   3.043 
> system.time( dat2 <-  reshape(dat, direction="long", varying=3:202, sep="_"))
   user  system elapsed 
 16.766   8.608  25.272 

そのプロセス中に 32 GB メモリの合計の約 1/5 が使用され、目標の 250 分の 1 であったと言えます。したがって、マシンがハングしたことには驚きません。(「クラッシュ」するべきではありません。R の作成者は、動作の正確な説明を提供することを望んでおり、仮想メモリにページングしたときに R プロセスが応答を停止したのではないかと考えています。) 32 GB を使用した場合、700 万レコード x 100 列のデータセット。

于 2013-05-11T09:29:27.693 に答える