対話型Rセッションの使用可能なメモリを管理するために、人々はどのようなトリックを使用しますか?以下の関数を使用して(2004年のPetr PikalとDavid Hindsによるr-helpリストへの投稿に基づいて)最大のオブジェクトをリスト(および/またはソート)し、それらのいくつかを時々rm()
します。しかし、最も効果的なソリューションは...十分なメモリを備えた64ビットLinuxで実行することでした。
みんなが共有したい他の素敵なトリックはありますか?投稿ごとに1つお願いします。
# 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)
}
頻繁な再起動の一般的な戦略をさらに説明するために、コマンドラインから直接単純な式を実行できる littler を使用できます。これは、単純なクロスプロド用に異なるBLASのタイミングをとるために時々使用する例です。
r -e'N<-3*10^3; M<-matrix(rnorm(N*N),ncol=N); print(system.time(crossprod(M)))'
同様に、
r -lMatrix -e'example(spMatrix)'
matrixパッケージを(--packages | -lスイッチを使用して)ロードし、spMatrix関数の例を実行します。 rは常に「新鮮」に開始するため、このメソッドはパッケージ開発中の優れたテストでもあります。
最後になりましたが、rは、 '#!/ usr/bin/r' Shebang-headerを使用したスクリプトでの自動バッチモードにも最適です。 Rscriptは、littlerが使用できない場合の代替手段です(Windowsなど)。
再現可能なスクリプトで作業を記録してください。時々、Rを再度開いてから、スクリプトをsource()
開きます。使用しなくなったものはすべて削除し、追加の利点としてコードをテストします。
data.table パッケージを使用します。 :=
演算子を使用すると、次のことができます。
これらの操作はいずれも(おそらく大きな)data.table
を一度もコピーしません。
data.table
が使用する作業メモリがはるかに少ないため、集計も特に高速です。関連リンク :
これをTwitterの投稿で見て、Dirkのすばらしい機能だと思います! 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") })
データフレームを回帰関数のdata=
引数に渡すときに、必要な変数のみを選択してsubset
パラメーターを積極的に使用します。数式と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
}
それは良いトリックです。
もう1つの提案は、可能な限りメモリ効率の良いオブジェクトを使用することです。たとえば、data.frameの代わりにマトリックスを使用します。
これは実際にはメモリ管理に対応していませんが、広く知られていない重要な機能の1つは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
残念ながら、広範囲にテストする時間はありませんでしたが、今まで見たことのないメモリのヒントを紹介します。私にとって、必要なメモリは50%以上削減されました。 read.csvなどを使用してRにデータを読み込む場合、一定量のメモリが必要です。この後、save("Destinationfile",list=ls())
でそれらを保存できます。次にRを開いたときにload("Destinationfile")
を使用できます。これでメモリ使用量が減少した可能性があります。これにより、異なるデータセットで同様の結果が得られるかどうかを確認できればいいでしょう。
Rワークスペースを保存することはありません。インポートスクリプトとデータスクリプトを使用して、頻繁に再作成したくない特に大きなデータオブジェクトをファイルに出力します。この方法では、常に新しいワークスペースから開始し、大きなオブジェクトを削除する必要はありません。ただし、これは非常に便利な機能です。
速度とメモリの両方の目的で、いくつかの複雑な一連の手順を介して大きなデータフレームを構築する場合、(構築中の進行中のデータセット)を定期的にディスクにフラッシュし、前に来たものに追加してから再起動します。この方法では、中間ステップは小さなデータフレームでのみ機能します(たとえば、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()
は、Dirkの.ls.objects()
カスタム関数(以前の回答で詳しく説明)のかなり良い代替品のように思えますが、data.frames/tablesであり、たとえば行列、配列、リスト。
幸いなことに、私の大きなデータセットは、約100 MB(32ビットバイナリ)の「チャンク」(サブセット)で機器に保存されます。したがって、データセットを融合する前に、前処理手順(情報価値のない部分の削除、ダウンサンプリング)を順番に行うことができます。
gc ()
を「手動で」呼び出すと、データのサイズが使用可能なメモリに近づいた場合に役立ちます。
場合によっては、別のアルゴリズムで必要なメモリがはるかに少なくなります。
ベクトル化とメモリ使用の間にはトレードオフがある場合があります。
比較:split
&lapply
vs. for
ループ。
高速で簡単なデータ分析のために、私はしばしば最初にデータの小さなランダムなサブセット(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
functionは、各オブジェクトのメモリ使用量も表示できます。
gdata::ll(unit='MB')
4 GBのRAM(Windows 10を実行しているので、現実的には2 GB以上に1 GBにします)の割り当てには十分注意する必要がありました。
私はdata.tableをほぼ独占的に使用しています。
「fread」関数を使用すると、インポート時にフィールド名で情報をサブセット化できます。実際に必要なフィールドのみをインポートします。ベースR読み取りを使用している場合は、インポート直後に偽の列をヌルにします。
42-が示唆するように、可能な限り、情報をインポートした直後に列内でサブセット化します。
不要になったらすぐに、環境からオブジェクトを頻繁にrm()します。それらを使用して別のサブセットを作成し、gc()を呼び出した後の次の行。
data.tableの 'fread'および 'fwrite'は、ベースRの読み取りおよび書き込みと比較してveryになります。
kpierce8が示唆しているように、私はほとんどすべての環境からすべてを書き込み、それを元に戻します。これにより、環境が「クリーン」に保たれ、メモリ割り当てが低く抑えられるだけでなく、おそらくRAMの深刻な不足が原因で、Rはコンピューターで頻繁にクラッシュする傾向があります。本当に頻繁に。コードがさまざまな段階を経てドライブ自体に情報がバックアップされるということは、クラッシュしても最初からやり直す必要がないことを意味します。
2017年現在、最速のSSDはM2ポートを介して1秒あたり数GB程度実行されていると思います。プライマリディスクとして使用する基本的な50GB Kingston V300(550MB/s)SSDがあります(WindowsとRが搭載されています)。私はすべてのバルク情報を安価な500GB WD Platterに保管しています。作業を開始したら、データセットをSSDに移動します。これは、すべてを「フレッド」および「フライト」と組み合わせることで、うまく機能しています。 「ff」を使用してみましたが、前者の方が好きです。ただし、4Kの読み取り/書き込み速度では、この問題が発生する可能性があります。 SSDからPlatterへの25万個の1kファイル(250MB相当)のバックアップには数時間かかる場合があります。私の知る限り、「チャンク化」プロセスを自動的に最適化できるRパッケージはまだありません。例えばユーザーのRAM容量を確認し、RAM /接続されているすべてのドライブの読み取り/書き込み速度をテストして、最適な「チャンク化」プロトコルを提案します。これにより、ワークフローの大幅な改善/リソースの最適化が可能になります。例えば分割... RAMのMB->分割... SSDのMB->分割...プラッタのMB->分割...テープのMB事前にデータセットをサンプリングして、より現実的なゲージスティックを提供することができます。
私がRで取り組んだ問題の多くは、組み合わせと順列のペア、トリプルなどを形成することを伴います。これにより、制限されたRAMが制限されることが多くなります少なくとも =ある点で指数関数的に展開します。これにより、後でクリーンアップしようとするのではなく、開始する情報の量とは対照的に、品質に多くの注意を集中させました。開始する情報を準備する際の一連の操作(最も単純な操作から開始し、複雑さを増す)。例えばサブセット、マージ/ジョイン、組み合わせ/順列などを形成します。
場合によっては、ベースRの読み取りと書き込みを使用することにはいくつかの利点があるようです。たとえば、「fread」内でのエラー検出は非常に優れているため、Rに実際に乱雑な情報を取得してクリーンアップを試みるのは困難です。 Linuxを使用している場合、Base Rもはるかに簡単に思えます。 Base RはLinuxで正常に動作するようで、Windows 10は〜20GBのディスク容量を使用しますが、Ubuntuは数GBしか必要とせず、Ubuntuで必要なRAMはわずかに低くなります。しかし、(L)Ubuntuにサードパーティのパッケージをインストールすると、大量の警告とエラーに気付きました。 Linuxで(L)Ubuntuまたは他のストックディストリビューションから遠く離れることはお勧めしません)。一部のLinuxユーザーではこれはうまくいきませんが、いくつかのカスタムディストリビューションは目新しさを超えて無意味です(Linuxだけを何年も使ってきました)。
うまくいけば、そのいくつかが他の人を助けるかもしれない。
リークを本当に回避したい場合は、グローバル環境で大きなオブジェクトを作成しないでください。
私が通常やることは、ジョブを実行してNULL
を返す関数を使用することです。すべてのデータは、この関数またはそれが呼び出す他の関数で読み取られ、操作されます。
これは上記に何も追加しませんが、私が好きなシンプルでコメントの多いスタイルで書かれています。 sizeで順序付けられたオブジェクトを含むテーブルを生成しますが、上記の例で与えられた詳細の一部はありません。
#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]))),])
Linuxで作業していて、複数のプロセスを使用し、1つ以上のread操作のみを行う必要がある場合ラージオブジェクトmakeForkCluster
の代わりにmakePSOCKcluster
を使用します。これにより、ラージオブジェクトを他のプロセスに送信する時間も節約できます。
Rを閉じてsource
を発行し、コマンドラインを使用することを提案する@hadleyと@Dirkに続いて、上記の回答のいくつかに本当に感謝しています。数百の質量スペクトルを処理する必要があり、それぞれが約20 Mbのメモリを占有するため、次のように2つの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;
#NOTE: Set LOAD to TRUE if you want to load saved file
#NOTE: Set LOAD to FALSE if you want to generate and save
if(LOAD == TRUE) { OBJECT <- readRDS(file = 'MySavedObject.rds'); } else
{ OBJECT <- COMPLICATED.FUNCTION(x, y, z);
saveRDS(file = 'MySavedObject.rds', object = OBJECT); }
```
このコード構造では、オブジェクトを生成して保存するか、既存の保存済みファイルから直接ロードするかによってLOAD
を変更するだけです。 (もちろん、最初に生成して保存する必要がありますが、その後、ロードするオプションがあります。)LOAD = TRUE
を設定すると、複雑な関数の使用がバイパスされ、その中の重い計算がすべて回避されます。このメソッドは、目的のオブジェクトを格納するのに十分なメモリを必要としますが、コードを実行するたびに計算する必要がなくなります。中間ステップの多くの重い計算を必要とするオブジェクトの場合(たとえば、大きな配列でのループを含む計算の場合)、これによりかなりの時間と計算を節約できます。
上記の回答で与えられたより一般的なメモリ管理手法と同様に、私は常にオブジェクトのサイズを可能な限り縮小しようとします。たとえば、非常に大きいが非常にまばらな行列、つまり、ほとんどの値がゼロである行列を操作します。 'Matrix'パッケージ(資本化が重要)を使用して、次のように平均オブジェクトサイズを〜2GBから〜200MBに減らすことができました。
my.matrix <- Matrix(my.matrix)
Matrixパッケージには、通常のマトリックスとまったく同じように使用できるデータ形式(他のコードを変更する必要はありません)が含まれていますが、メモリにロードするかディスクに保存するかにかかわらず、スパースデータをはるかに効率的に格納できます。
さらに、私が受け取る生のファイルは、各データポイントが変数x, y, z, i
を持つ「long」形式です。データを変数i
のみを使用してx * y * z
次元配列に変換する方がはるかに効率的です。
データを把握し、少し常識を働かせてください。
これは、この優れた古い質問に対する新しい回答です。ハドレーのアドバンストRから:
install.packages("pryr")
library(pryr)
object_size(1:10)
## 88 B
object_size(mean)
## 832 B
object_size(mtcars)
## 6.74 kB
また、knitrを使用して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)
複数の中間ファイルが必要な場合は、temp1
、temp2
、temp3
を使用します。
テストにはtest
、test2
、...を使用します.
ランニング
for (i in 1:10)
gc(reset = T)
また、Rは未使用のメモリを解放するのに役立ちます。