Frage

Ich würde gerne die Logik verstehen, die R verwendet, wenn Argumente an Funktionen übergeben, Kopien von Variablen erstellt usw. werden.in Bezug auf die Speichernutzung.Wann erstellt es tatsächlich eine Kopie der Variablen vs.einfach einen Verweis auf diese Variable übergeben?Insbesondere die Situationen, auf die ich neugierig bin, sind:

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

Is a wörtlich übergeben werden oder ist ein Hinweis auf ein Übergeben werden?

x <- 1
y <- x

Referenz der Kopie?Wann ist das nicht der Fall?

Wenn mir das jemand erklären könnte, würde ich mich sehr freuen.

War es hilfreich?

Lösung

Wenn Variablen übergeben werden, erfolgt dies immer per Kopie und nicht per Referenz.Manchmal erhalten Sie jedoch keine Kopie, bis tatsächlich eine Zuordnung erfolgt.Die eigentliche Beschreibung des Prozesses ist Pass-by-promise.Schauen Sie sich die Dokumentation an

?force
?delayedAssign

Eine praktische Implikation ist, dass es sehr schwierig, wenn nicht sogar unmöglich ist, zu vermeiden, dass mindestens doppelt so viel RAM benötigt wird, wie Ihre Objekte nominell belegen.Das Ändern eines großen Objekts erfordert im Allgemeinen das Erstellen einer temporären Kopie.

Update:2015:Ich stimme (und stimme) Matt Dowle zu, dass seine Daten.das Tabellenpaket bietet eine alternative Route zur Zuweisung, die das Problem der Kopier-Duplizierung vermeidet.Wenn dies das angeforderte Update war, habe ich es zum Zeitpunkt des Vorschlags nicht verstanden.

Es gab kürzlich eine Änderung in R 3.2.1 in den Bewertungsregeln für apply und Reduce.Es wurde SO angekündigt mit Bezug auf die Nachrichten hier: Anonyme Funktionen von lapply zurückgeben - was läuft falsch?

Und die interessantes Papier, das von jhetzel in den Kommentaren zitiert wurde, ist jetzt hier:

Andere Tipps

Späte Antwort, aber ein sehr wichtiger Aspekt des Sprachdesigns, der im Web (oder zumindest in den üblichen Quellen) nicht genügend Beachtung findet.

x <- c(0,4,2)
lobstr::obj_addr(x)
# [1] "0x7ff25e82b0f8"
y <- x
lobstr::obj_addr(y)
# [1] "0x7ff25e82b0f8"

Beachten Sie die identische "Speicheradresse", d. h.der Speicherort, an dem das Objekt gespeichert ist.Damit können Sie bestätigen, dass x und y beide zeigen auf dieselbe Kennung.

Hadley Wickhams fortgeschrittenes R-Buch berührt dies:

Betrachten Sie diesen Code:

x <- c(1, 2, 3)

Es ist einfach, es als zu lesen:"erstelle ein Objekt mit dem Namen 'x', enthält die Werte 1, 2 und 3".Leider ist das ein vereinfachung, die zu ungenauen Vorhersagen darüber führt, was R tut tatsächlich hinter den Kulissen.Es ist genauer zu sagen, dass dieser Code macht zwei Dinge:

Es erstellt ein Objekt, einen Vektor von Werten, c(1, 2, 3).Und es ist binden dieses Objekts an einen Namen, x.Mit anderen Worten, das Objekt oder wert, hat keinen Namen;es ist eigentlich der Name, der einen Wert hat.

Beachten Sie, dass die Speicheradressen kurzlebig sind und sich mit jeder neuen R-Sitzung ändern.

Jetzt ist hier der wichtige Teil.

In der R-Semantik werden Objekte nach Wert kopiert.Dies bedeutet, dass das Modifizieren die Kopie lässt das ursprüngliche Objekt intakt.Seit dem Kopieren von Daten in speicher ist eine teure Operation, Kopien in R sind so faul wie möglich.Sie treten nur auf, wenn das neue Objekt tatsächlich geändert wird.Quelle:[Englische Dokumentation][1]

Wenn wir also jetzt den Wert von ändern y durch Anhängen eines Werts an den Vektor, y zeigt jetzt auf ein anderes "Objekt".Dies stimmt mit den Angaben in der Dokumentation zu einem Kopiervorgang überein, der "nur dann ausgeführt wird, wenn das neue Objekt geändert wird" (lazy). y zeigt auf eine andere Adresse als zuvor.

y <- c(y, -3)
print(lobstr::obj_addr(y))
# [1] "0x7ff25e825b48"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top