Tricks zur Verwaltung des verfügbaren Speichers in Sitzung R

Welche Tricks verwenden die Leute, um den verfügbaren Speicher einer interaktiven R-Sitzung zu verwalten? Ich benutze die folgenden Funktionen [basierend auf den Mitteilungen von Peter Pikal und David Hind in der r-help-Liste von 2004], um die größten Objekte aufzuzählen (und / oder zu sortieren), und manchmal auch einige davon. Die effektivste Lösung war jedoch, dass sie unter 64-Bit-Linux mit ausreichend Arbeitsspeicher ausgeführt wurde.

Alle anderen interessanten Tricks, die die Leute teilen möchten? Eine für die Nachricht, bitte.

 # 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) } 
459
31 авг. eingestellt von Dirk Eddelbuettel 31. August 2009-08-31 18:26 09 um 18:26 Uhr 2009-08-31 18:26
@ 26 Antworten

Zur weiteren Veranschaulichung der allgemeinen Strategie für häufige Neustarts können wir littler verwenden , wodurch wir einfache Ausdrücke direkt von der Befehlszeile aus ausführen können. Hier ist ein Beispiel, das ich manchmal während eines anderen BLAS für eine einfache Crossprod verwende.

  r -e'N<-3*10^3; M<-matrix(rnorm(N*N),ncol=N); print(system.time(crossprod(M)))' 

Ähnlich

  r -lMatrix -e'example(spMatrix)' 

lädt das Matrix-Paket (über die Option -packages | -l) und führt Beispiele für die Funktion spMatrix aus. Da r immer "frisch" beginnt, ist diese Methode auch ein guter Test bei der Entwicklung eines Pakets.

Nicht zuletzt ist es auch für den automatischen Stapelmodus in Skripts mit dem Shebang-Header "#! / Usr / bin / r" geeignet. Rscript ist eine Alternative, bei der Littler nicht verfügbar ist (z. B. in Windows).

25
01 сент. Antwort von Dirk Eddelbuettel 01. September 2009-09-01 01:26 09 um 01:26 Uhr 2009-09-01 01:26

Stellen Sie sicher, dass Sie Ihre Arbeit in einem abspielbaren Skript aufzeichnen. Öffne R von Zeit zu Zeit erneut, dann source() dein Skript. Sie löschen alles, was Sie nicht mehr benötigen, und Ihr Code wird als zusätzlicher Nutzen geprüft.

border=0
180
31 авг. Die Antwort wurde am 31. August von Hadley gegeben . 2009-08-31 19:09 09 um 19:09 2009-08-31 19:09

Ich verwende data.table . Mit dem Operator := Sie:

  • Fügen Sie Spalten als Referenz hinzu
  • Ändern Sie Teilmengen vorhandener Spalten nach Verweis und nach Gruppen nach Verweis
  • Spalten durch Verweis entfernen

Keine dieser Operationen kopiert (möglicherweise große) data.table überhaupt nicht einmal.

  • Die Aggregation ist auch besonders schnell, da data.table viel weniger Arbeitsspeicher benötigt.

Verwandte Links:

147
10 авг. Antwort von Matt Dowle 10 Aug. 2012-08-10 13:13 '12 am 13:13 2012-08-10 13:13

Ich habe es auf Twitter gesehen und dachte, es wäre eine großartige Funktion von Dirk! Im Anschluss an JD Long würde ich es für das einfache Lesen tun:

 # 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() 

Dies führt zu folgendem:

  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 

HINWEIS. Der Hauptteil, den ich hinzugefügt habe, war (wieder aus der Antwort von JD):

 obj.prettysize <- napply(names, function(x) { print(object.size(x), units = "auto") }) 
101
28 янв. Antwort von Tony Breyal 28. Januar 2011-01-28 14:46 '11 am 14:46 2011-01-28 14:46

Ich mag das Dirk.ls.objects () -Skript, aber ich schielte weiter, um die Zeichen in der Größenspalte zu zählen. Also habe ich ein paar hässliche Hacks gemacht, um es mit hübscher Formatierung für die Größe zu präsentieren:

 .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 } 
48
09 марта '10 в 18:59 2010-03-09 18:59 Die Antwort wird von JD Long am 9. März 10 um 18:59 Uhr 2010-03-09 18:59 gegeben

Ich verwende den subset Parameter aktiv mit der Auswahl nur der erforderlichen Variablen, wenn Daten in das Argument data= der Regressionsfunktionen übertragen werden. Dies führt zu einigen Fehlern, wenn ich vergesse, Variablen sowohl zur Formel als auch zum select= -Vektor hinzuzufügen. Dies spart jedoch immer noch viel Zeit, da weniger Objekte kopiert werden und der Speicher erheblich reduziert wird. Nehmen wir an, ich habe 4 Millionen Einträge mit 110 Variablen (und ich mache das.) Beispiel:

 # 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") ) ) 

Im Kontext von Kontext und Strategie: Die Variable gdlab2 ist ein logischer Vektor, der für Objekte in einem Datensatz erstellt wurde, die alle normalen oder nahezu normalen Werte für eine Gruppe von Labortests HIVfinal , und HIVfinal war ein Vektorsymbol, das die vorläufigen und bestätigenden Tests für HIV zusammenfasste.

47
05 дек. Die Antwort wird am 42-05 Dezember gegeben. 2010-12-05 21:15 '10 um 21:15 2010-12-05 21:15

Das ist ein guter Trick.

Ein anderer Vorschlag ist die Verwendung möglichst effizienter Speicherobjekte: Verwenden Sie beispielsweise eine Matrix anstelle einer Matrix data.frame.

Dies gilt nicht für die Speicherverwaltung, aber eine wichtige Funktion, die nicht häufig verwendet wird, ist memory.limit (). Sie können den Standardwert mit diesem Befehl memory.limit (Größe = 2500) erhöhen, wobei die Größe in MB angegeben ist. Wie Dirk bemerkt hat, müssen Sie 64-Bit verwenden, um dies voll ausnutzen zu können.

33
31 авг. Die Antwort ist Shane 31 Aug gegeben. 2009-08-31 22:08 09 um 22:08 2009-08-31 22:08

Ich mag die verbesserte Funktion von Objekten, die von Dirk entwickelt wurde. Meist reicht mir aber die Basisausgabe mit Name und Größe des Objekts. Hier ist eine einfachere Funktion mit einem ähnlichen Zweck. Die Speichernutzung kann in alphabetischer Reihenfolge oder nach Größe geordnet werden, kann auf eine bestimmte Anzahl von Objekten begrenzt und in aufsteigender oder absteigender Reihenfolge angeordnet werden. Außerdem arbeite ich oft mit Daten von 1 GB +, so dass die Funktion die Einheiten entsprechend ändert.

 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)) } 

Und hier ist ein Beispiel für die Ausgabe:

 > 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 
31
23 марта '12 в 16:21 2012-03-23 16:21 Die Antwort wurde von Michael Hallquist am 23. März '12 um 16:21 Uhr 2012-03-23 ​​16:21 gegeben

Leider hatte ich keine Zeit, es gründlich zu testen, aber hier ist ein Erinnerungstipp, den ich vorher noch nicht gesehen hatte. Für mich wurde der Speicherbedarf um mehr als 50% reduziert. Wenn Sie Material in R lesen, z. B. read.csv, ist ein gewisser Speicherplatz erforderlich. Danach können Sie sie mit save("Destinationfile",list=ls()) Sie R das nächste Mal öffnen, können Sie load("Destinationfile") Nun kann die Speicherbelegung abnehmen. Es wäre schön, wenn jemand bestätigen könnte, ob er mit einem anderen Datensatz ähnliche Ergebnisse liefert.

30
07 окт. Antwort von Dennis Jaheruddin 07. Okt. 2011-10-07 12:37 '11 am 12:37 PM 2011-10-07 12:37

Ich speichere niemals den Arbeitsbereich R. Ich verwende Importskripte und Datenskripte und gebe besonders große Datenobjekte aus, die ich nicht oft in Dateien neu erstellen möchte. So beginne ich immer mit einem neuen Arbeitsbereich und muss keine großen Objekte reinigen. Dies ist eine sehr schöne Funktion.

28
01 сент. Die Antwort ist kpierce8 01 sep . 2009-09-01 00:37 09 um 0:37 2009-09-01 00:37

Wenn Sie sowohl aus Geschwindigkeits- als auch aus Speichergründen einen großen Datenrahmen mit einigen wenigen komplexen Schritten erstellen, lese ich ihn regelmäßig (den eingebauten Datensatz) auf die Festplatte, füge etwas hinzu, was zuvor war, und starte ihn neu. Zwischenstufen funktionieren daher nur mit kleinen Datenrahmen (was beispielsweise gut ist, da rbind die Arbeit mit größeren Objekten erheblich ver>

 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 ) 
23
01 февр. Die Antwort wird von Ben BL 01 Feb. gegeben. 2011-02-01 17:52 '11 um 17:52 2011-02-01 17:52

Beachten Sie, dass das data.table package tables() ein guter Ersatz für die benutzerdefinierte .ls.objects() Funktion ist (die in früheren Antworten ausführlich beschrieben wurde), obwohl dies für data.frames / tables gilt und nicht beispielsweise. Matrizen, Arrays, Listen.

17
11 окт. Die Antwort wird von Geotheorie 11. Oktober gegeben. 2013-10-11 13:59 '13 am 13:59 2013-10-11 13:59
  • Ich hatte Glück, und meine großen Datensätze werden in „Chunks“ (Subsets) von etwa 100 MB (32-Bit-Binärcode) gespeichert. Auf diese Weise kann ich vor dem Zusammenführen des Datensatzes sequentiell Vorverarbeitungsschritte ausführen (nicht informative Teile entfernen, Downsampling durchführen).

  • gc () manuelle Aufrufen von gc () kann hilfreich sein, wenn sich die Datengröße dem verfügbaren Speicher nähert.

  • Manchmal benötigt ein anderer Algorithmus viel weniger Speicher.
    Manchmal gibt es einen Kompromiss zwischen Vektorisierung und Speichernutzung.
    Vergleiche: split und lapply versus for Schleife.

  • Für eine schnelle und einfache Datenanalyse arbeite ich oft zuerst mit einer kleinen zufälligen Untermenge ( sample () ) von Daten. Nach der Analyse des Datenskripts /. Rnw der Datenanalysecode ist abgeschlossen, und die vollständigen Daten werden pro Nacht / über die Wochenend- / ... Berechnung an den Berechnungsserver übertragen.

14
22 мая '12 в 16:12 2012-05-22 16:12 Die Antwort wird Cbeleites gegeben 22. Mai 12 um 16:12 Uhr 2012-05-22 16:12

Verwenden Sie Umgebungen anstelle von Listen, um Sammlungen von Objekten zu verarbeiten, die einen erheblichen Arbeitsspeicher beanspruchen.

Grund: Bei jeder Änderung des Listenstrukturelements wird die gesamte Liste vorübergehend dupliziert. Dies wird zu einem Problem, wenn der Speicherbedarf in der Liste etwa die Hälfte des verfügbaren Arbeitsspeichers beträgt, da dann die Daten durch eine >

Hier ist ein Beispiel:

 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)) 

In Kombination mit Strukturen wie big.matrix oder data.table , mit denen Sie deren Inhalte ändern können, kann eine sehr effektive Speichernutzung erreicht werden.

11
06 февр. die antwort wird von geor feb 06 gegeben 2014-02-06 13:47 '14 um 13:47 2014-02-06 13:47

Die ll Funktion im gData Paket gData auch die Speicherbelegung für jedes Objekt anzeigen.

 gdata::ll(unit='MB') 
7
26 янв. die antwort wird von user1436187 26 jan gegeben. 2014-01-26 05:58 '14 um 5:58 2014-01-26 05:58

Mit nur 4 GB RAM (unter Windows 10, also etwa 2 oder mehr realistische 1 GB), muss ich bei der Verteilung sehr vorsichtig sein.

Ich verwende fast ausschließlich data.table.

Mit der Funktion "fread" können Sie während des Imports Informationen zu Feldnamen multiplizieren. Importieren Sie die Felder, die Sie wirklich benötigen, um loszulegen. Wenn Sie die Lesebasis R verwenden, führen Sie die falschen Spalten sofort nach dem Import aus.

Wie in der 42. Ausgabe gezeigt, werde ich, wenn es möglich ist, unmittelbar nach dem Import der Informationen innerhalb der Spalten multiplizieren.

Oft rm () Objekte aus der Umgebung, sobald sie nicht mehr benötigt werden. in der nächsten Zeile, nachdem Sie sie für eine Teilmenge von etwas anderem verwendet haben, und rufen Sie gc () auf.

'fread' und 'fwrite' von data.table können im Vergleich zur R-Basis sehr schnell sein, lesen und schreiben.

Wie kpierce8 sagt, entferne ich fast immer alles aus der Umgebung und korrigiere es, auch wenn Tausende / Hunderttausende kleiner Dateien durchlaufen werden. Dies schützt nicht nur die Umwelt und hält die Speicherbelegung niedrig, sondern R führt aufgrund meines schwerwiegenden RAM-Mangels häufig zu Abstürzen auf meinem Computer. sehr oft. Nachdem die Informationen auf der Festplatte selbst gesichert wurden, da der Code verschiedene Phasen durchläuft, muss ich nicht von vorne anfangen, wenn er funktioniert.

Ab 2017 denke ich, dass die schnellsten SSD-Geräte durch den M2-Port für ein paar GB pro Sekunde arbeiten. Ich habe ein wirklich einfaches 50-Gigabyte-SSD-Laufwerk Kingston V300 (550 MB / s), das ich als Hauptlaufwerk verwende (es hat Windows und R). Ich speichere alle Masseninformationen auf einer billigen 500-Gramm-WD-Diskette. Ich verschiebe Datensätze auf SSD, wenn ich anfange, daran zu arbeiten. In Kombination mit "fread" und "fwrite" funktioniert alles einwandfrei. Ich habe versucht, 'ff' zu verwenden, aber ich bevorzuge die erste. 4K-Lese- / Schreibgeschwindigkeiten können Probleme verursachen. Das Sichern einer Viertelmillion Dateien von 1 000 (250 MB) von einer SSD auf ein Tablet kann mehrere Stunden dauern. Soweit ich weiß, gibt es noch kein R-Paket, das den Prozess der "Chunkifizierung" automatisch optimieren kann. Sehen Sie sich beispielsweise an, wie viel Arbeitsspeicher vorhanden ist, überprüfen Sie die Lese- / Schreibgeschwindigkeit des RAM / aller angeschlossenen Laufwerke und schlagen Sie dann das optimale Protokoll für die "Chunkifizierung" vor. Dies kann zu erheblichen Verbesserungen der Workflow- / Ressourcenoptimierung führen. Teilen Sie ihn beispielsweise durch ... MB für RAM → Teilen Sie ihn durch ... MB für SSD → Teilen Sie ihn durch ... MB auf einem Teller → Teilen Sie ihn durch ... MB in Band. Er könnte Daten vorab eingeben, um einen realistischeren Stift zu erhalten.

Viele der Probleme, mit denen ich in R gearbeitet habe, hängen mit der Bildung von Kombinationen und Paaren von Permutationen, Tripeln usw. zusammen, die die Beschränkung des RAM auf eine Einschränkung beschränken, da sie sich an einem bestimmten Punkt oft zumindest exponentiell ausdehnen. Deshalb konzentrierte ich mich auf die Qualität und nicht auf die Menge der Informationen, die zuerst in sie eingegeben wurden, anstatt später zu versuchen, sie zu löschen, und auf die Reihenfolge der Vorgänge, um Informationen für den Start vorzubereiten (beginnend mit der einfachsten Operation und zunehmender Komplexität). B. eine Teilmenge, dann zusammenführen / zusammenführen, dann Formatierungen von Kombinationen / Permutationen usw.

In einigen Fällen scheint das Lesen und Schreiben der Basis R einige Vorteile zu haben. Zum Beispiel ist das Erkennen von Fehlern in "fread" so gut, dass es schwierig sein kann, wirklich schmutzige Informationen in R zu erhalten, um sie zu löschen. Base R scheint auch viel einfacher zu sein, wenn Sie Linux verwenden. Base R scheint unter Linux gut zu funktionieren, Windows 10 benötigt ~ 20 GB Speicherplatz, während Ubuntu nur wenige GB benötigt, der für Ubuntu benötigte Arbeitsspeicher ist jedoch etwas geringer. Bei der Installation von Drittanbieter-Paketen in (L) Ubuntu sind jedoch viele Warnungen und Fehler aufgetreten. Ich würde nicht empfehlen, zu weit von (L) Ubuntu oder anderen Linux-Distributionen zu driften, da diese allgemeine Kompatibilität verloren gehen kann, was den Prozess fast bedeutungslos macht (Ich denke, "Unity" sollte in Ubuntu ab 2017 eingestellt werden). . Ich verstehe, dass dies mit einigen Linux-Benutzern nicht gut übereinstimmen wird, aber einige der Distros der Benutzer sind über die Grenzen der Neuheit hinaus bedeutungslos (ich habe jahre>

Hoffe, dass einige von ihnen anderen helfen können.

6
06 июня '17 в 4:26 2017-06-06 04:26 Die Antwort ist gegeben bg49ag 6. Juni 17 um 04:26 2017-06-06 04:26

Wenn Sie wirklich Lecks vermeiden möchten, sollten Sie keine großen Objekte in einer globalen Umgebung erstellen.

Normalerweise verwende ich eine Funktion, die die Aufgabe ausführt und NULL zurückgibt - alle Daten werden in dieser Funktion oder in den anderen, die sie aufrufen, gelesen und verarbeitet.

6
20 июля '14 в 8:43 2014-07-20 08:43 Die Antwort wurde von Alexander Radev am 20. Juli '14 um 8:43 2014-07-20 08:43 gegeben

Es fügt dem oben genannten nichts hinzu, ist jedoch in einem einfachen und hoch kommentierten Stil geschrieben, der mir gefällt. Es gibt eine Tabelle mit Objekten, die nach Größe sortiert sind, jedoch ohne einige der in den obigen Beispielen angegebenen Details:

 #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]))),]) 
5
26 апр. Antwort von JamesF am 26. April 2016-04-26 14:55 '16 um 14:55 Uhr 2016-04-26 14:55

Wenn Sie mit Linux arbeiten und mehrere Prozesse verwenden makeForkCluster und makePSOCKcluster für ein oder mehrere große Objekte ausführen müssen , verwenden Sie makeForkCluster anstelle von makePSOCKcluster . Es spart auch die Zeit für das Senden eines großen Objekts an andere Prozesse.

3
14 нояб. die antwort wird von gdkrmr 14 nov. gegeben . 2017-11-14 22:56 17 um 22:56 Uhr 2017-11-14 22:56

Ich schätze einige der obigen Antworten wirklich sehr, nachdem @hadley und @Dirk gefolgt wurden, die anbieten, R zu schließen und eine source auszugeben und die Befehlszeile zu verwenden. Ich habe eine Lösung gefunden, die für mich sehr gut funktioniert hat. Мне приходилось иметь дело с сотнями масс-спектров, каждый из которых занимает около 20 Мб памяти, поэтому я использовал два сценария 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)) } } 

с этим script Я в основном контролирую, что мой основной script сделать runConsensus.r , и я пишу ответ данных для вывода. При этом каждый раз, когда обертка вызывает script, кажется, что R снова открывается и память освобождается.

Hoffe das hilft.

2
ответ дан user1265067 23 июля '14 в 15:20 2014-07-23 15:20

Это более новый ответ на этот отличный старый вопрос. От Hadley Advanced 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 )

2
ответ дан Chris Beeley 23 февр. '18 в 20:49 2018-02-23 20:49

Как и более общие методы управления памятью, приведенные в ответах выше, я всегда стараюсь как можно меньше уменьшить размер моих объектов. Например, я работаю с очень большими, но очень разреженными матрицами, другими словами, матрицами, где большинство значений равно нулю. Используя пакет "Матрица" (важная капитализация), я смог уменьшить средние размеры объекта от ~ 2 до 200 МБ так же, как:

 my.matrix <- Matrix(my.matrix) 

Пакет Matrix включает в себя форматы данных, которые можно использовать точно как обычная матрица (не нужно менять другой код), но они могут хранить разреженные данные намного эффективнее, независимо от того, загружены они в память или сохранены на диск.

Кроме того, необработанные файлы, которые я получаю, находятся в "длинном" формате, где каждая точка данных имеет переменные x, y, z, i . Гораздо эффективнее преобразовать данные в массив измерения x * y * z с переменной i .

Знайте свои данные и используйте немного здравого смысла.

2
ответ дан D Greenwood 31 марта '16 в 18:22 2016-03-31 18:22

Вы также можете получить некоторую выгоду, используя knitr, и поместите свой script в Rmd chuncks.

Я обычно делю код в разных кусках и выбираю, какой из них будет сохранять контрольную точку в кеше или в файл RDS, а

Там вы можете установить кусок, который будет сохранен в "кеш", или вы можете решить запустить или не использовать определенный фрагмент. Таким образом, в первом запуске вы можете обрабатывать только "часть 1", другое исполнение вы можете выбрать только "часть 2" и т.д.

Beispiel:

 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) ``` 

Как побочный эффект, это также может сэкономить вам некоторые головные боли с точки зрения воспроизводимости:)

1
ответ дан Matias Thayer 16 июня '16 в 17:47 2016-06-16 17:47

На основе @ @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() 
1
ответ дан ilyas 29 окт. '17 в 18:16 2017-10-29 18:16

Совет по работе с объектами, требующими сложных промежуточных вычислений: при использовании объектов, для создания которых требуется много тяжелых вычислений и промежуточных шагов, я часто нахожу полезным написать фрагмент кода с функцией для создания объекта, а затем отдельный фрагмент кода, который дает мне возможность либо сгенерировать и сохранить объект в виде файла 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 обойти использование моей сложной функции и избежать всех тяжелых вычислений в ней. Этот метод все еще требует достаточно памяти для хранения интересующего вас объекта, но он избавляет вас от необходимости вычислять его каждый раз, когда вы запускаете свой код. Для объектов, которые требуют большого количества сложных вычислений промежуточных шагов (например, для вычислений, включающих циклы над большими массивами), это может сэкономить значительное количество времени и вычислений.

0
ответ дан Ben 14 янв. '19 в 3:32 2019-01-14 03:32

Starten

 for (i in 1:10) gc(reset = T) 

время от времени также помогает R освобождать неиспользуемую, но еще не освобожденную память.

0
ответ дан Marcelo Ventura 20 мая '16 в 7:41 2016-05-20 07:41

Другие вопросы по меткам или Задайте вопрос