2017-11-07 3 views
2

나는 효율적인 방법으로 여러 datatables를 rbind하고 싶습니다. 더 정확하게R data.table 메모리 효율적인 rbindlist

, 내 기억은 크기 의 경우 나는 (I 크기 KN data.tables에 가입 할 수 있도록, 그들에게 이동에 하나씩, 무료 메모리를 rbind 싶습니다 n + 1) * k. 내가 생각했던 것에도 불구하고,

rbindlistOneByOne <- function(l, use.names=FALSE, fill=FALSE, idcol=NULL, verbose = F) { 
    ll <- length(l) 
    # Handle empty lists 
    if(ll <= 0) stop("rbindlistOneByOne : empty list") 
    if(ll <= 1) return(l[[1]]) 
    # Handle normal lists (ll > 2) 
    current <- l[[1]] 
    res <- current 
    l[1] <- NULL 
    rm(current); gc() 
    for(i in 2:ll) { 
    current <- l[[1]] 
    res <- rbindlist(list(res, current), use.names = use.names, fill = fill, idcol = idcol) 
    l[1] <- NULL 
    rm(current); gc() 
    } 
    return(res) 
} 

이제 문제는이 기능 하지 메모리 효율적이다 :

나는 그렇게 희망이 기능을 썼다.

이유를 알고 계십니까? RM이 메모리를 비우지 않아서 "현재"라는 data.table이 메모리에 남아 있기 때문입니까?

+0

'data.table'의 내장'rbindlist()'함수를 사용하면 어떻게됩니까? – Uwe

+2

l - 딥 복사가 없으므로 rbindlist (l)은 매우 효율적입니다. – Roland

+0

나는'gc()'가 내가 원하는 것처럼 메모리에서 제거하지 않은 똑같은 문제를 겪었다. (매우 비효율적 인 방식으로)이 작업은 일련의 작업을 수행하고 RDS 파일에 쓰고 개체를 삭제 한 다음 메모리를 지우고 RDS 파일을 다시 읽은 다음 작업을 계속하는 것입니다. 나는이 접근법을 취해야 만 했으므로 로컬 메모리를 최대한으로 활용하고 있었다. –

답변

1

원하는 작업을 수행 할 수있는 방법이 없습니다. 메모리 릴리즈는 당신이 그것을 제어 할 수없는 확률 론적입니다. gc()을 사용하면 메모리가 해제되거나 해제 될 수 있으며 사용자가 제어 할 수 없습니다. http://adv-r.had.co.nz/memory.html에서

: 당신이 다른 곳에서 읽을 수도 무엇에도 불구하고

, GC를 호출 할 필요() 자신이 결코 없습니다. R은 더 많은 공간이 필요할 때마다 가비지 콜렉션을 자동으로 실행합니다. 그 값을보고 싶다면 gcinfo (TRUE)를 호출하십시오. gc()를 호출하는 유일한 이유는 메모리에 운영 체제를 반환하도록 R에 요청하는 것입니다. 그러나 그다지 효과가 없을 수도 있습니다. 이전 버전의 Windows에서는 프로그램이 메모리를 OS로 반환 할 방법이 없었습니다.

또한 gc을 호출하는 속도가 매우 느립니다. 여기 gc없이 10 선 1000 개 테이블의 목록을

  • gc를 호출하지 않고와 함수의 bechmark : gc
  • 8 MS : 7의

rbindlist이 가장 효율적입니다 bind 할 방법 data.table

+0

고맙습니다. 나는 인 - 메모리 대신에 ROM에서 역변환을위한 해결책을 찾고있을 것이다. – VeilleData