2013-05-19 2 views
1

짧은에 운영 할 때 RAM에 너무 큰 될 큰 목록 작업? 어떻게 예를 들어, <code>R</code>에 큰 목록 작업을 디스크에 넣어 다음 섹션에서 작업 할 수 있습니다, 더 많은 RAM을 가진 시스템에서 작업의

다음은 목록에있는 각 데이터 프레임 여기에 빠른 예와는 달리, 고유 내 실제 사용의 경우 내가
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) 

을 사용하고 목록의 유형을 생성하는 일부 코드입니다. 이 몇 시간 동안 실행

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

내 실제 사용 케이스 : 나는이 내가 dataframes이 목록에 수행 할 작업의 한 예입니다 100,000

= 4000와 나는 N을 목표로하고 있습니다 의 RAM을 채우고 스왑의 가장 다음 RStudio는 (RStudio 인해 R 세션에서 오류로 종료하도록 강요했다) 얼고 그 위에 폭탄으로 메시지를 보여줍니다.

나는 bigmemory이 행렬로 제한되고 ff은 목록을 처리하지 않는 것으로 보입니다. 다른 옵션은 무엇입니까? 여기에 sqldf 또는 관련 메모리 부족 방법이 가능한 경우 어떻게 시작할 수 있습니까? 어떤 진전을 이루기 위해 문서에서 충분한 정보를 얻을 수 없으며 어떤 조언을해도 감사 할 것입니다. "더 많은 RAM 구매"지침은 무시됩니다. 이것은 평균적인 데스크탑 컴퓨터 (예 : 대학 컴퓨터 실)에 적합 할 것으로 기대되는 패키지를위한 것입니다.

UPDATE SimonO101과 아리의 도움이 의견을 최대 Followining는, 여기에 결과가 여기와와와 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) 

없이 dataframes 및 data.tables, 루프와 lapply을 비교 일부 벤치 마크이고, 명시 적 가비지 수집이 없으면 data.table은 루프보다 약간 더 빠르며 느리게 실행됩니다. 명시 적 가비지 콜렉션 (SimonO101이 제안하는 것 같아서)은 모두 동일한 속도입니다. 훨씬 느립니다! 나는 gc를 사용하여 약간의 논란이 경우 아마 도움이되지 않습니다 것을 알고,하지만 난 그것을 내 실제 사용 사례와 함께 총을 제공하고 어떤 차이가 있는지 확인할 수 있습니다. 물론 필자는 이러한 함수들에 대한 메모리 사용에 관한 어떠한 데이터도 갖고 있지 않다. 이것이 나의 주요 관심사이다. 타이밍 기능과 동일한 메모리 벤치마킹 기능이 없다 (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 
+1

은 당신이 즉, 그것은 사전에 데이터의 여러 사본을하지 않습니다, 그것은 참조로 값을 변경하기 때문에 data.table' 여기에 엄청난 도움이 될 수있는 경우'에서'data.rame' 구조를 사용하는 참조하십시오. 나는 전체 테이블을 개최 RAM에 필요한 공간을 제외하고, 그것을 알고있는 것처럼, 필요한 경우에만 추가 작업 RAM 공간은 긴 목록 요소 (예를 들어,'column')의 길이에 달려있다. 반면에'data.frame'을 사용하면 객체를 작업 할 때 훨씬 더 많은 RAM이 필요합니다. 참조에 의한 변경으로 인해 'data.table'도 * 훨씬 * 빠릅니다. 이 같은'lapply'를 사용하는 경우 –

+1

또한, 나는 그것의 많은 data.frames에 걸쳐 반복, 가비지 컬렉터의 복잡한 너무 잘 모르겠지만, * (그러나 이것은 추측입니다) * 가능 이미 처리 된 데이터에 가비지 콜렉션.* lapply' 루프가 종료 된 후 * 메모리가 가득 찰 때까지 메모리의 프레임이 * 발생할 수 없습니다. 아마도 다른 구조/루핑 메커니즘이 여기에 적합할까요? –

+1

@ SimonO101 나는 동의한다. 나는'luply'를 사용하여 몇 가지 큰 작업을 실패 시켰습니다. 이것은'for' 루프에 간단한 재 작성으로 작업했습니다. –

답변

1

당신은 정말 매우 큰 데이터는 파일을 HDF5 쓸 h5r 패키지를 사용할 수 있습니다 사용할하려는 경우. RAM을 사용하는 대신 하드 드라이브에 쓰고 읽는 것이 좋습니다. 나는 이것을 사용하지 않았기 때문에 일반적인 사용법에 대해서는별로 도움이되지 않을 수있다. 왜냐하면 그것에 대한 튜토리얼이 없다고 생각하기 때문이다. 나는 pytables에 대해 생각함으로써이 아이디어를 얻었다. 이 솔루션이 적합한 지 확신하지 못합니다.

+0

제안에 감사드립니다. 나는 다시 여기로 돌아 오기 위해 여기에두고있다. http://bioconductor.org/packages/2.11/bioc/html/rhdf5.html – Ben

+0

그건 다른 패키지이다. h5r 패키지가 더 강력하다고 들었습니다 : http://cran.r-project.org/web/packages/h5r/index.html – JEquihua

+0

예, 옵션을 수집합니다. 당신은 견고성에 대해 알고있는 것에 대해 대답에 조금 더 자세하게 추가 할 수 있습니까? hdf5는 완전히 새로운 것입니다! – Ben