R 세션에서 사용 가능한 메모리를 관리하는 방법
사람들은 대화형 R 세션의 사용 가능한 메모리를 관리하기 위해 어떤 트릭을 사용합니까? David 글을 으로 함] 큰 를 나열 정렬 가끔 저는 [2004년 년칼피힌드또비즈하및이r-help목록에로올린아가하여큰개장나가를체열/정끔는렬고래용사을능기으반에을기가글과터피데또▁i▁below▁[하--▁occ및▁and▁functions▁list▁the▁byassionally가▁use▁inbased]정▁objects)고끔)저렬▁list는/rm()
그들 중 일부.그러나 가장 효과적인 솔루션은 충분한 메모리를 갖춘 64비트 리눅스에서 실행하는 것이었습니다.
사람들이 공유하고 싶은 다른 멋진 묘기가 있나요?우편 한 통에 하나씩 주세요.
# improved list of objects
.ls.objects <- function (pos = 1, pattern, order.by,
decreasing=FALSE, head=FALSE, n=5) {
napply <- function(names, fn) sapply(names, function(x)
fn(get(x, pos = pos)))
names <- ls(pos = pos, pattern = pattern)
obj.class <- napply(names, function(x) as.character(class(x))[1])
obj.mode <- napply(names, mode)
obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
obj.size <- napply(names, object.size)
obj.dim <- t(napply(names, function(x)
as.numeric(dim(x))[1:2]))
vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
obj.dim[vec, 1] <- napply(names, length)[vec]
out <- data.frame(obj.type, obj.size, obj.dim)
names(out) <- c("Type", "Size", "Rows", "Columns")
if (!missing(order.by))
out <- out[order(out[[order.by]], decreasing=decreasing), ]
if (head)
out <- head(out, n)
out
}
# shorthand
lsos <- function(..., n=10) {
.ls.objects(..., order.by="Size", decreasing=TRUE, head=TRUE, n=n)
}
재현 가능한 스크립트에 작업을 기록해야 합니다.때때로 R을 다시 연 다음source()
항목은 할 수 .더 이상 사용하지 않는 항목은 모두 삭제되며, 추가적인 이점으로 코드를 테스트할 수 있습니다.
저는 data.table 패키지를 사용합니다.그것과 함께:=
하여 다음을 수행할수 .
- 참조로 열 추가
- 참조로 기존 열의 부분 집합 수정 및 참조로 그룹 수정
- 참조로 열 삭제
중 것도이 있는) 작대중어러않지다습니복하사있음수것이도일업떤모한규대▁the▁none▁(ations▁copy(▁of있음다▁oper)않수pot습니▁these) 복사하지 않습니다.data.table
단 한 번도.
- 집계속특빠릅다니히도도다니▁aggreg▁is 때문에 집계 속도가 특히 빠릅니다. 다음과 같은 이유로
data.table
훨씬 적은 작업 메모리를 사용합니다.
관련 링크:
트위터 게시물에서 이것을 보고 더크의 멋진 기능이라고 생각했습니다!JD Long의 답변에 이어, 저는 사용자 친화적인 읽기를 위해 이것을 할 것입니다.
# improved list of objects
.ls.objects <- function (pos = 1, pattern, order.by,
decreasing=FALSE, head=FALSE, n=5) {
napply <- function(names, fn) sapply(names, function(x)
fn(get(x, pos = pos)))
names <- ls(pos = pos, pattern = pattern)
obj.class <- napply(names, function(x) as.character(class(x))[1])
obj.mode <- napply(names, mode)
obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
obj.prettysize <- napply(names, function(x) {
format(utils::object.size(x), units = "auto") })
obj.size <- napply(names, object.size)
obj.dim <- t(napply(names, function(x)
as.numeric(dim(x))[1:2]))
vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
obj.dim[vec, 1] <- napply(names, length)[vec]
out <- data.frame(obj.type, obj.size, obj.prettysize, obj.dim)
names(out) <- c("Type", "Size", "PrettySize", "Length/Rows", "Columns")
if (!missing(order.by))
out <- out[order(out[[order.by]], decreasing=decreasing), ]
if (head)
out <- head(out, n)
out
}
# shorthand
lsos <- function(..., n=10) {
.ls.objects(..., order.by="Size", decreasing=TRUE, head=TRUE, n=n)
}
lsos()
이는 다음과 같은 결과를 초래합니다.
Type Size PrettySize Length/Rows Columns
pca.res PCA 790128 771.6 Kb 7 NA
DF data.frame 271040 264.7 Kb 669 50
factor.AgeGender factanal 12888 12.6 Kb 12 NA
dates data.frame 9016 8.8 Kb 669 2
sd. numeric 3808 3.7 Kb 51 NA
napply function 2256 2.2 Kb NA NA
lsos function 1944 1.9 Kb NA NA
load loadings 1768 1.7 Kb 12 2
ind.sup integer 448 448 bytes 102 NA
x character 96 96 bytes 1 NA
참고: 제가 추가한 주요 부분은 (다시 말하지만, JD의 답변에서 수정됨)입니다.
obj.prettysize <- napply(names, function(x) {
print(object.size(x), units = "auto") })
저는 공격적으로 그것을 사용합니다.subset
을 에 전달할 때할 수 있는 변수입니다.data=
회귀 함수의 인수입니다.공식과 다음 두 가지 모두에 변수를 추가하는 것을 잊어버린 경우 오류가 발생합니다.select=
벡터이지만 개체 복사가 감소하여 시간이 많이 절약되고 메모리 설치 공간이 크게 줄어듭니다.가 있는 개의 있다고 . (는 있습니다.) 110개의 변수로 400개의 레코드를 가지고 있습니다.예:
# library(rms); library(Hmisc) for the cph,and rcs functions
Mayo.PrCr.rbc.mdl <-
cph(formula = Surv(surv.yr, death) ~ age + Sex + nsmkr + rcs(Mayo, 4) +
rcs(PrCr.rat, 3) + rbc.cat * Sex,
data = subset(set1HLI, gdlab2 & HIVfinal == "Negative",
select = c("surv.yr", "death", "PrCr.rat", "Mayo",
"age", "Sex", "nsmkr", "rbc.cat")
) )
: 맥과전설는방법하정략을락:방법:gdlab2
모든 또는 입니다.HIVfinal
HIV에 대한 예비 및 확인 테스트를 요약한 문자 벡터입니다.
저는 Dirk의 .ls.objects() 스크립트를 좋아하지만, 계속해서 눈을 가늘게 뜨고 크기 열에 문자를 세었습니다.그래서 크기에 맞는 예쁜 포맷으로 선물하기 위해 추악한 해킹을 했습니다.
.ls.objects <- function (pos = 1, pattern, order.by,
decreasing=FALSE, head=FALSE, n=5) {
napply <- function(names, fn) sapply(names, function(x)
fn(get(x, pos = pos)))
names <- ls(pos = pos, pattern = pattern)
obj.class <- napply(names, function(x) as.character(class(x))[1])
obj.mode <- napply(names, mode)
obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
obj.size <- napply(names, object.size)
obj.prettysize <- sapply(obj.size, function(r) prettyNum(r, big.mark = ",") )
obj.dim <- t(napply(names, function(x)
as.numeric(dim(x))[1:2]))
vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
obj.dim[vec, 1] <- napply(names, length)[vec]
out <- data.frame(obj.type, obj.size,obj.prettysize, obj.dim)
names(out) <- c("Type", "Size", "PrettySize", "Rows", "Columns")
if (!missing(order.by))
out <- out[order(out[[order.by]], decreasing=decreasing), ]
out <- out[c("Type", "PrettySize", "Rows", "Columns")]
names(out) <- c("Type", "Size", "Rows", "Columns")
if (head)
out <- head(out, n)
out
}
좋은 수작입니다.
또 다른 제안은 가능한 한 메모리 효율적인 개체를 사용하는 것입니다. 예를 들어 data.frame 대신 matrix를 사용하는 것입니다.
이것은 실제로 메모리 관리를 다루지는 않지만 널리 알려지지 않은 한 가지 중요한 기능은 memory.limit()입니다.memory.limit(size=2500) 명령을 사용하여 기본값을 늘릴 수 있습니다. 여기서 크기는 MB 단위입니다.Dirk가 언급했듯이, 이것을 실질적으로 활용하려면 64비트를 사용해야 합니다.
저는 Dirk가 개발한 향상된 객체 기능을 매우 좋아합니다.대부분의 경우 객체 이름과 크기가 포함된 더 기본적인 출력으로 충분합니다.여기 비슷한 목적을 가진 더 간단한 기능이 있습니다.메모리 사용은 알파벳 또는 크기별로 정렬할 수 있으며, 특정 개체 수로 제한할 수 있으며, 오름차순 또는 내림차순으로 정렬할 수 있습니다.또한 1GB 이상의 데이터를 자주 사용하기 때문에 그에 따라 기능이 변경됩니다.
showMemoryUse <- function(sort="size", decreasing=FALSE, limit) {
objectList <- ls(parent.frame())
oneKB <- 1024
oneMB <- 1048576
oneGB <- 1073741824
memoryUse <- sapply(objectList, function(x) as.numeric(object.size(eval(parse(text=x)))))
memListing <- sapply(memoryUse, function(size) {
if (size >= oneGB) return(paste(round(size/oneGB,2), "GB"))
else if (size >= oneMB) return(paste(round(size/oneMB,2), "MB"))
else if (size >= oneKB) return(paste(round(size/oneKB,2), "kB"))
else return(paste(size, "bytes"))
})
memListing <- data.frame(objectName=names(memListing),memorySize=memListing,row.names=NULL)
if (sort=="alphabetical") memListing <- memListing[order(memListing$objectName,decreasing=decreasing),]
else memListing <- memListing[order(memoryUse,decreasing=decreasing),] #will run if sort not specified or "size"
if(!missing(limit)) memListing <- memListing[1:limit,]
print(memListing, row.names=FALSE)
return(invisible(memListing))
}
다음은 몇 가지 출력 예입니다.
> showMemoryUse(decreasing=TRUE, limit=5)
objectName memorySize
coherData 713.75 MB
spec.pgram_mine 149.63 kB
stoch.reg 145.88 kB
describeBy 82.5 kB
lmBandpass 68.41 kB
R 작업영역은 저장하지 않습니다.스크립트 가져오기 및 데이터 스크립트를 사용하고 자주 재생성하지 않을 특히 큰 데이터 개체를 파일로 출력합니다.이렇게 하면 항상 새로운 작업 공간에서 시작하고 큰 개체를 정리할 필요가 없습니다.하지만 그것은 매우 좋은 기능입니다.
안타깝게도 광범위하게 테스트할 시간이 없었지만 이전에 본 적이 없는 메모리 팁이 있습니다.필요한 메모리가 50% 이상 감소했습니다.예를의 memoryread.csv 파일을 R에 .이 후에는 다음을 사용하여 저장할 수 있습니다.save("Destinationfile",list=ls())
을 열 는 다에을열수있습다니사할용을 사용할 수 .load("Destinationfile")
이제 메모리 사용량이 감소했을 수 있습니다.이것이 다른 데이터 세트로 유사한 결과를 생성하는지 확인할 수 있는 사람이 있다면 좋을 것입니다.
자주 다시 시작하는 일반적인 전략을 자세히 설명하기 위해 명령줄에서 직접 간단한 식을 실행할 수 있는 더 적게 사용할 수 있습니다.여기 제가 가끔 사용하는 예가 있습니다. 단순한 크로스 프로드에 대해 다른 BLAS 시간을 측정하는 데 사용합니다.
r -e'N<-3*10^3; M<-matrix(rnorm(N*N),ncol=N); print(system.time(crossprod(M)))'
저도 마찬가지예요.
r -lMatrix -e'example(spMatrix)'
는 ( --packages | -l 스위치를 통해) 매트릭스 패키지를 로드하고 spMatrix 함수의 예제를 실행합니다.r은 항상 '새로' 시작하기 때문에 이 방법은 패키지 개발 중에도 좋은 테스트입니다.
마지막으로 중요한 것은 '#!/usr/bin/r' 셰방헤더를 사용하는 스크립트의 자동 배치 모드에서도 잘 작동합니다.Rscript는 Windows 등에서 사용할 수 없는 경우의 대안입니다.
속도와 메모리 측면에서 복잡한 일련의 단계를 통해 대용량 데이터 프레임을 구축할 때는 주기적으로 Disk에 플러시(구축 중인 진행 중인 데이터 세트)하여 이전에 발생한 모든 데이터에 추가한 다음 다시 시작합니다.이러한 방식으로 중간 단계는 작은 데이터 프레임에서만 작동합니다(예: rbind는 더 큰 개체에서 상당히 느려집니다).모든 중간 개체가 제거되면 프로세스가 끝나면 전체 데이터 세트를 다시 읽을 수 있습니다.
dfinal <- NULL
first <- TRUE
tempfile <- "dfinal_temp.csv"
for( i in bigloop ) {
if( !i %% 10000 ) {
print( i, "; flushing to disk..." )
write.table( dfinal, file=tempfile, append=!first, col.names=first )
first <- FALSE
dfinal <- NULL # nuke it
}
# ... complex operations here that add data to 'dfinal' data frame
}
print( "Loop done; flushing to disk and re-reading entire data set..." )
write.table( dfinal, file=tempfile, append=TRUE, col.names=FALSE )
dfinal <- read.table( tempfile )
로 참로고.data.table
포의장tables()
더크의 대체품으로 꽤 괜찮은 것 같습니다..ls.objects()
사용자 정의 함수(이전 답변에 나와 있음). 단, data.frames/matrix 및 참고(예: 행렬, 배열, 목록)에 대해서만 사용할 수 있습니다.
운이 좋아서 대용량 데이터 세트는 계측기에서 약 100MB(32비트 이진수)의 "청크"(하위 세트)로 저장됩니다.따라서 데이터 세트를 융합하기 전에 사전 처리 단계(정보가 없는 부품 삭제, 다운샘플링)를 순차적으로 수행할 수 있습니다.
하기 르기
gc ()
"크기가 사용 한 메모리에 될 수 있습니다손으로" 데이터 크기가 사용 가능한 메모리에 가까워질 경우 도움이 될 수 있습니다.때때로 다른 알고리즘은 훨씬 적은 메모리를 필요로 합니다.
때때로 벡터화와 메모리 사용 사이에 균형이 잡히기도 합니다.
비교:split
&lapply
a.a.afor
루우프분석을 , 는 종종 부분 빠르쉬데분이위해석, 저작무부집분합위작은을종종고운터는▁(▁with▁for빠집(▁first합부▁work▁a▁analysis분▁subset▁i)을 먼저 작업합니다.
sample ()
스크립트 한 번.일단 데이터 분석 스크립트/.Rnw가 완료된 데이터 분석 코드이며 전체 데이터는 계산 서버로 이동하여 오버나이트 / 오버주말 / ... 계산합니다.
상당한 양의 작업 메모리를 차지하는 개체 컬렉션을 처리하기 위해 목록 대신 환경을 사용하는 것입니다.
그이는의 : 매어떤요소가번.list
구조가 수정되고 전체 목록이 일시적으로 복제됩니다.이 문제는 목록의 스토리지 요구량이 사용 가능한 작업 메모리의 절반 정도인 경우에 발생합니다. 이는 데이터를 느린 하드 디스크로 스왑해야 하기 때문입니다.그러나 환경은 이러한 동작의 영향을 받지 않으며 목록과 유사하게 처리될 수 있습니다.
다음은 예입니다.
get.data <- function(x)
{
# get some data based on x
return(paste("data from",x))
}
collect.data <- function(i,x,env)
{
# get some data
data <- get.data(x[[i]])
# store data into environment
element.name <- paste("V",i,sep="")
env[[element.name]] <- data
return(NULL)
}
better.list <- new.env()
filenames <- c("file1","file2","file3")
lapply(seq_along(filenames),collect.data,x=filenames,env=better.list)
# read/write access
print(better.list[["V1"]])
better.list[["V2"]] <- "testdata"
# number of list elements
length(ls(better.list))
다과같 구은함께과조와 같은 와 함께 합니다.big.matrix
또는data.table
컨텐츠를 변경할 수 있으므로 매우 효율적인 메모리 사용이 가능합니다.
그ll
에서 합니다.gData
패키지는 각 개체의 메모리 사용량도 표시할 수 있습니다.
gdata::ll(unit='MB')
누출을 방지하려면 지구 환경에서 큰 물체를 만들지 않아야 합니다.
제가 주로 하는 일은 그 일을 하고 돌아오는 기능을 갖는 것입니다.NULL
모든 데이터는 이 함수 또는 호출되는 다른 함수에서 읽고 조작됩니다.
단 4GB의 RAM(Windows 10을 실행하므로 2GB 이상을 현실적으로 1GB로 설정)을 사용하면 할당에 매우 신중해야 했습니다.
저는 data.table을 거의 독점적으로 사용합니다.
'fread' 기능을 사용하면 가져올 때 필드 이름을 기준으로 정보의 부분 집합을 지정할 수 있습니다. 실제로 시작하는 데 필요한 필드만 가져올 수 있습니다.기본 읽기를 사용하는 경우 가져오기 직후에 가상 열을 null로 지정합니다.
42-가 제안하는 바와 같이 가능한 경우 정보를 가져온 후 즉시 열 내에서 부분 집합을 설정합니다.
저는 종종 더 이상 필요하지 않은 개체를 환경에서 rm()하는 경우가 많습니다. 예를 들어 개체를 사용하여 다른 개체의 하위 집합을 지정한 후 gc()를 호출합니다.
data.table의 'fread' 및 'fwrite'는 기본 R 읽기 및 쓰기에 비해 매우 빠를 수 있습니다.
kpierse8에서 제안하는 바와 같이, 저는 거의 항상 환경에서 모든 것을 지우고 수천 또는 수십만 개의 작은 파일을 처리해야 하는 경우에도 다시 사용합니다.이것은 환경을 '깨끗하게' 유지하고 메모리 할당을 낮게 유지할 뿐만 아니라, 사용 가능한 RAM의 심각한 부족으로 인해 R은 내 컴퓨터에서 자주 충돌하는 경향이 있습니다. 정말 자주 충돌합니다.코드가 여러 단계를 거치면서 드라이브 자체에 정보가 백업된다는 것은 충돌이 발생할 경우 처음부터 바로 시작할 필요가 없다는 것을 의미합니다.
2017년 기준으로 가장 빠른 SSD는 M2 포트를 통해 초당 몇 GB 정도 실행되고 있다고 생각합니다.기본 Disk로 사용하는 50GB Kingston V300(550MB/s) SSD(Windows 및 R 포함)가 있습니다.저는 모든 대량 정보를 저렴한 500GB WD 플래터에 보관합니다.작업을 시작하면 데이터 세트를 SSD로 이동합니다.이것은 'freading'과 'fwrite'를 결합하여 모든 것이 잘 진행되고 있습니다.저는 'ff'를 사용해 보았지만 전자를 선호합니다. 4K 읽기/쓰기 속도로 인해 문제가 발생할 수 있습니다. SSD에서 플래터로 1k 파일 25만 개(250MB 상당)를 백업하는 데는 몇 시간이 걸릴 수 있습니다.제가 알기로는 '청크화' 프로세스를 자동으로 최적화할 수 있는 R 패키지가 아직 없습니다. 예를 들어, 사용자가 RAM 용량을 확인하고 RAM/연결된 모든 드라이브의 읽기/쓰기 속도를 테스트한 다음 최적의 '청크화' 프로토콜을 제안합니다.이를 통해 워크플로우가 크게 개선되거나 리소스가 최적화될 수 있습니다. 예를 들어 RAM의 경우 ...MB로 분할 -> SSD의 경우 ...MB로 분할 -> ...로 분할 등이 있습니다.접시 위의 MB -> 그것을 ...로 나눕니다.MB가 테이프에 있습니다.데이터 세트를 미리 샘플링하여 보다 현실적인 게이지 스틱으로 작업할 수 있습니다.
제가 R에서 연구한 많은 문제들은 조합과 순열 쌍, 트리플 등을 형성하는 것과 관련이 있는데, 이는 제한된 RAM이 적어도 어느 시점에서는 기하급수적으로 확장되는 경우가 많기 때문에 제한적인 RAM을 갖는 것을 더 제한적으로 만들 뿐입니다.이것은 제가 나중에 정리하려고 하기보다는 시작할 정보의 양에 비해 품질에 많은 관심을 기울이게 만들었습니다. 그리고 시작할 정보를 준비할 때의 작업 순서(가장 단순한 작업으로 시작하여 복잡성을 증가시키는 것).그런 다음 병합/결합, 조합/순열 등을 형성합니다.
경우에 따라 기본 R 읽기 및 쓰기를 사용하면 몇 가지 이점이 있는 것 같습니다.예를 들어, 'fread' 내의 오류 감지가 너무 좋아서 R에 정말 엉망인 정보를 정리하기 시작하는 것이 어려울 수 있습니다.또한 Linux를 사용하는 경우 R 기반이 훨씬 더 쉬워 보입니다.기본 R은 Linux에서 잘 작동하는 것으로 보이며, Windows 10은 최대 20GB의 디스크 공간을 사용하는 반면 Ubuntu는 몇 GB만 필요하지만 Ubuntu에 필요한 RAM은 약간 낮습니다.하지만 (L)Ubuntu에서 타사 패키지를 설치할 때 많은 양의 경고와 오류를 발견했습니다.저는 (L)Ubuntu 또는 Linux의 다른 주식 배포판에서 너무 멀리 이동하는 것을 권장하지 않습니다. 왜냐하면 당신이 전체적인 호환성을 너무 많이 완화할 수 있기 때문에 프로세스가 거의 무의미해질 수 있기 때문입니다('unity'는 2017년 우분투에서 취소될 예정이라고 생각합니다).나는 이것이 일부 Linux 사용자들에게는 잘 먹히지 않을 것이라는 것을 알고 있지만, 일부 사용자 지정 배포는 참신함 이상으로 무의미합니다(나는 Linux만 사용하며 수년을 보냈습니다).
그것들 중 일부가 다른 사람들을 도울 수 있기를 바랍니다.
이것은 이 훌륭한 오래된 질문에 대한 새로운 대답입니다.해들리의 고급 R에서:
install.packages("pryr")
library(pryr)
object_size(1:10)
## 88 B
object_size(mean)
## 832 B
object_size(mtcars)
## 6.74 kB
(http://adv-r.had.co.nz/memory.html)
이것은 위에 아무것도 추가되지 않고, 제가 좋아하는 단순하고 묵직한 스타일로 작성되었습니다.위의 예제에서 제공된 세부 정보를 제외하고 크기순으로 정렬된 개체가 있는 테이블을 생성합니다.
#Find the objects
MemoryObjects = ls()
#Create an array
MemoryAssessmentTable=array(NA,dim=c(length(MemoryObjects),2))
#Name the columns
colnames(MemoryAssessmentTable)=c("object","bytes")
#Define the first column as the objects
MemoryAssessmentTable[,1]=MemoryObjects
#Define a function to determine size
MemoryAssessmentFunction=function(x){object.size(get(x))}
#Apply the function to the objects
MemoryAssessmentTable[,2]=t(t(sapply(MemoryAssessmentTable[,1],MemoryAssessmentFunction)))
#Produce a table with the largest objects first
noquote(MemoryAssessmentTable[rev(order(as.numeric(MemoryAssessmentTable[,2]))),])
위의 답변에서 제시한 보다 일반적인 메모리 관리 기술뿐만 아니라 항상 개체의 크기를 최대한 줄이려고 노력합니다.예를 들어, 저는 매우 크지만 매우 희박한 행렬, 즉 대부분의 값이 0인 행렬을 사용합니다.'Matrix' 패키지(자본화 중요)를 사용하여 평균 개체 크기를 2GB에서 200MB로 간단하게 줄일 수 있었습니다.
my.matrix <- Matrix(my.matrix)
매트릭스 패키지에는 일반 매트릭스와 똑같이 사용할 수 있지만(다른 코드를 변경할 필요가 없음) 희소 데이터를 메모리에 로드하든 디스크에 저장하든 훨씬 더 효율적으로 저장할 수 있는 데이터 형식이 포함되어 있습니다.
제가 각가 있는 'long'x, y, z, i
를 데터를보효변수있환로로 변환하는 더 입니다.x * y * z
i
.
데이터를 알고 상식을 사용합니다.
Linux에서 작업 중이고 여러 프로세스를 사용하고 하나 이상의 큰 개체에 대해 읽기 작업만 수행하면 되는 경우makeForkCluster
신에대 makePSOCKcluster
이렇게 하면 큰 개체를 다른 프로세스로 보내는 시간도 절약됩니다.
R을 발행할 것을 하는 @위의 중 몇 합니다.source
그리고 명령줄을 사용하여 저에게 매우 효과적인 솔루션을 생각해냈습니다.각각 약 20Mb의 메모리를 차지하는 수백 개의 질량 스펙트럼을 처리해야 했기 때문에 다음과 같이 두 개의 R 스크립트를 사용했습니다.
먼저 포장지:
#!/usr/bin/Rscript --vanilla --default-packages=utils
for(l in 1:length(fdir)) {
for(k in 1:length(fds)) {
system(paste("Rscript runConsensus.r", l, k))
}
}
이 스크립트를 사용하여 기본적으로 내 주요 스크립트가 수행하는 작업을 제어합니다.runConsensus.r
출력에 대한 데이터 답변을 작성합니다.이를 통해 래퍼가 스크립트를 호출할 때마다 R이 다시 열리고 메모리가 해방되는 것처럼 보입니다.
도움이 되길 바랍니다.
과도한 중간 계산이 필요한 물체를 처리하기 위한 팁:만들기 위해 많은 양의 계산과 중간 단계가 필요한 객체를 사용할 때, 저는 종종 객체를 만들기 위한 함수를 가진 코드 덩어리를 작성한 다음 객체를 생성하고 저장할 수 있는 옵션을 제공하는 별도의 코드 덩어리를 작성하는 것이 유용하다는 것을 알게 됩니다.rmd
하거나, 일파또로드서에서 합니다.rmd
이미 저장한 파일입니다. 이은특쉽할수있다니습게에서 하기 .R Markdown
다음과 같은 코드 변환 구조를 사용합니다.
```{r Create OBJECT}
COMPLICATED.FUNCTION <- function(...) { Do heavy calculations needing lots of memory;
Output OBJECT; }
```
```{r Generate or load OBJECT}
LOAD <- TRUE
SAVE <- TRUE
#NOTE: Set LOAD to TRUE if you want to load saved file
#NOTE: Set LOAD to FALSE if you want to generate the object from scratch
#NOTE: Set SAVE to TRUE if you want to save the object externally
if(LOAD) {
OBJECT <- readRDS(file = 'MySavedObject.rds')
} else {
OBJECT <- COMPLICATED.FUNCTION(x, y, z)
if (SAVE) { saveRDS(file = 'MySavedObject.rds', object = OBJECT) } }
```
이 코드 구조로, 내가 할 일은 단지 변경하는 것입니다.LOAD
개체를 생성할지 아니면 기존 저장된 파일에서 직접 로드할지에 따라 달라집니다. (물론 처음에는 생성하여 저장해야 하지만, 이 이후에는 로드할 수 있습니다.) 정LOAD <- TRUE
복잡한 함수의 사용을 우회하고 그 안에 있는 모든 무거운 계산을 피합니다.이 방법을 사용하면 관심 개체를 저장할 수 있는 충분한 메모리가 필요하지만 코드를 실행할 때마다 개체를 계산할 필요가 없습니다.중간 단계(예: 대규모 어레이에 대한 루프를 포함하는 계산)를 많이 계산해야 하는 개체의 경우 상당한 시간과 계산을 절약할 수 있습니다.
입니다.
for (i in 1:10)
gc(reset = T)
또한 때때로 R이 사용되지 않았지만 여전히 해제되지 않은 메모리를 확보하는 데 도움이 됩니다.
당신은 또한 니트를 사용하고 대본을 Rmd 청크에 넣는 것을 통해 약간의 혜택을 얻을 수 있습니다.
저는 보통 코드를 여러 청크로 나누고 체크포인트를 캐시 또는 RDS 파일에 저장할 것인지 선택합니다.
여기서 "캐시"에 저장할 청크를 설정하거나 특정 청크를 실행할지 여부를 결정할 수 있습니다.이러한 방식으로 첫 번째 실행에서는 "부품 1"만 처리할 수 있고, 다른 실행에서는 "부품 2"만 선택할 수 있습니다.
예:
part1
```{r corpus, warning=FALSE, cache=TRUE, message=FALSE, eval=TRUE}
corpusTw <- corpus(twitter) # build the corpus
```
part2
```{r trigrams, warning=FALSE, cache=TRUE, message=FALSE, eval=FALSE}
dfmTw <- dfm(corpusTw, verbose=TRUE, removeTwitter=TRUE, ngrams=3)
```
부작용으로, 이것은 또한 재현성 측면에서 두통을 줄일 수 있습니다 :)
@Dirk와 @Tony의 답변을 바탕으로 약간의 업데이트를 했습니다.결과는 출력되었습니다.[1]
예쁜 사이즈 값보다 먼저, 그래서 나는 그것을 꺼냈습니다.capture.output
그것이 문제를 해결했습니다.
.ls.objects <- function (pos = 1, pattern, order.by,
decreasing=FALSE, head=FALSE, n=5) {
napply <- function(names, fn) sapply(names, function(x)
fn(get(x, pos = pos)))
names <- ls(pos = pos, pattern = pattern)
obj.class <- napply(names, function(x) as.character(class(x))[1])
obj.mode <- napply(names, mode)
obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
obj.prettysize <- napply(names, function(x) {
format(utils::object.size(x), units = "auto") })
obj.size <- napply(names, utils::object.size)
obj.dim <- t(napply(names, function(x)
as.numeric(dim(x))[1:2]))
vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
obj.dim[vec, 1] <- napply(names, length)[vec]
out <- data.frame(obj.type, obj.size, obj.prettysize, obj.dim)
names(out) <- c("Type", "Size", "PrettySize", "Rows", "Columns")
if (!missing(order.by))
out <- out[order(out[[order.by]], decreasing=decreasing), ]
if (head)
out <- head(out, n)
return(out)
}
# shorthand
lsos <- function(..., n=10) {
.ls.objects(..., order.by="Size", decreasing=TRUE, head=TRUE, n=n)
}
lsos()
저는 중간 단계가 많은 더 큰 프로젝트에서 작업할 때 물체의 양을 작게 유지하려고 노력합니다.그래서 많은 독특한 객체를 만드는 대신에,
dataframe
->step1
->step2
->step3
->result
raster
->multipliedRast
->meanRastF
->sqrtRast
->resultRast
나는 내가 부르는 임시 객체를 사용합니다.temp
.
dataframe
->temp
->temp
->temp
->result
따라서 중간 파일 수가 줄어들고 개요가 더 많이 표시됩니다.
raster <- raster('file.tif')
temp <- raster * 10
temp <- mean(temp)
resultRast <- sqrt(temp)
더 많은 메모리를 절약하기 위해 간단히 제거할 수 있습니다.temp
더 이상 필요하지 않을 때.
rm(temp)
파일이 여러 개 에는 중간파여개필경우요한러일이경우▁use,를 사용합니다.temp1
,temp2
,temp3
.
내가 사용하는 테스트용test
,test2
, ...
rm(list=ls())
정직함을 유지하고 사물을 재현할 수 있는 좋은 방법입니다.
언급URL : https://stackoverflow.com/questions/1358003/tricks-to-manage-the-available-memory-in-an-r-session
'programing' 카테고리의 다른 글
.NET 4.5로 업그레이드한 후 iFrame 파서 오류 발생 (0) | 2023.06.16 |
---|---|
모양 및 데이터 유형으로 배열을 할당할 수 없습니다. (0) | 2023.06.16 |
한 .R 파일에 모든 함수를 정의하고 다른 .R 파일에서 호출합니다.어떻게, 가능하다면요? (0) | 2023.06.16 |
Ruby: Ubuntu에 rmagick 설치하기 (0) | 2023.06.16 |
tqdm 진행 표시줄에 메시지를 추가할 수 있습니까? (0) | 2023.06.16 |