2012-05-18 10 views
15

Ich möchte die Logik verstehen, die R verwendet, wenn Argumente an Funktionen übergeben werden, Kopien von Variablen usw. in Bezug auf die Speichernutzung erstellen. Wann wird tatsächlich eine Kopie der Variablen erstellt oder nur ein Verweis auf diese Variable übergeben? Insbesondere über die Situationen, die ich neugierig bin, sind:R, tiefe vs. flache Kopien, Pass durch Referenz

f <- function(x) {x+1} 
a <- 1 
f(a) 

Ist a bestanden wörtlich werden oder ist ein Verweis auf ein übergeben wird?

x <- 1 
y <- x 

Referenz der Kopie? Wann ist das nicht der Fall?

Wenn mir jemand dies erklären könnte, würde ich es sehr zu schätzen wissen.

+3

Vielleicht finden Sie [diese] (http://cran.at.r-project.org/doc/manuals/R -lang.html # Evaluation) Abschnitt der R Sprachdefinition hilfreich. – joran

+2

Dieses Papier von Morandat und Kollegen hat eine interessante und kritische Diskussion der faulen Bewertung von Argumenten in R: http://www.cs.purdue.edu/homes/jv/pubs/ecoop12.pdf – jthetzel

+4

Verwenden Sie 'tracemem' auf einem entsprechend kompiliertes R kann zur Erkundung hilfreich sein, ebenso wie '.Internal (inspect (x))' mit einem Verständnis des 'NAM'ED-Feldes; Mein allgemeines Mantra lautet "copy-on-change", so dass zum Beispiel Ihr 'y <- x '(noch) keine Kopie auslöst, weil das Original, der Speicher, auf den' x' (und ' y ') ist' NAMED ', so dass die Modifikation von beiden eine Kopie auslöst. –

Antwort

12

Wenn es Variablen übergibt, ist es immer nach Kopie und nicht nach Referenz. Manchmal wird jedoch keine Kopie erstellt, bis tatsächlich eine Zuweisung erfolgt. Die eigentliche Beschreibung des Prozesses ist "Pass-by-Promise". Werfen Sie einen Blick in die Dokumentation

?force 
?delayedAssign 

Eine praktische Auswirkung ist, dass es sehr schwierig, wenn nicht unmöglich zu vermeiden, mindestens doppelt so viel RAM benötigen, wie Ihre Objekte nominell besetzen. Das Ändern eines großen Objekts erfordert normalerweise das Erstellen einer temporären Kopie.

Update: 2015: Ich stimme Matt Dowle zu (und tat), dass sein data.table-Paket einen alternativen Weg zur Zuweisung bietet, der das Kopierduplikationsproblem vermeidet. Wenn das Update angefordert wurde, habe ich es zum Zeitpunkt des Vorschlags nicht verstanden.

In R 3.2.1 wurden die Bewertungsregeln für apply und Reduce geändert. Es war so bekannt gegebenen unter Bezugnahme auf die News hier: Returning anonymous functions from lapply - what is going wrong?

Und die interesting paper cited by jhetzel in the comments is now here:

+8

Geben Sie ['data.table'] ein (http://datatable.r-forge.r-project.org/). Siehe "Kopieren" im Paket. Zuweisung durch Referenz ist möglich mit dem ': =' Operator, siehe '?": = "' Und die Reihe von 'set *' Funktionen. Anstatt Platz für 2-3 Kopien des gesamten Objekts zu benötigen, wollen wir nur noch eine Spalte Arbeitsspeicher oder weniger benötigen. –