Update Datenrahmen über function funktioniert nicht

Ich habe ein kleines Problem mit R …

Im folgenden Datenrahmen

test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0) 

Ich möchte Werte für v2 in den Zeilen ändern, in denen v1 1 ist.

 test[test$v1==1,"v2"] <- 10 

funktioniert gut.

 test v1 v2 1 1 10 2 1 10 3 1 10 4 2 0 5 2 0 6 2 0 

Allerdings muss ich das in einer function machen.

 test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0) test.fun <- function (x) { test[test$v1==x,"v2"] <- 10 print(test) } 

Der Aufruf der function scheint zu funktionieren.

 test.fun(1) v1 v2 1 1 10 2 1 10 3 1 10 4 2 0 5 2 0 6 2 0 

Aber wenn ich jetzt auf Test schaue:

 test v1 v2 1 1 0 2 1 0 3 1 0 4 2 0 5 2 0 6 2 0 

es hat nicht funktioniert. Gibt es einen Befehl, der R mitteilt, den Datenrahmen in der function wirklich zu aktualisieren? Vielen Dank für jede Hilfe!

test in Ihrer function eine Kopie des Objekts aus Ihrer globalen Umgebung (ich gehe davon aus, dass es dort definiert ist). Die Zuweisung erfolgt in der aktuellen Umgebung, sofern nicht anders angegeben. .GlobalEnv müssen Sie R mitteilen, dass Sie die lokale Kopie des test dem test in .GlobalEnv zuweisen .GlobalEnv .

Und es ist eine gute Form, alle notwendigen Objekte als Argumente an die function zu übergeben.

 test.fun < - function (x, test) { test[test$v1==x,"v2"] <- 10 assign('test',test,envir=.GlobalEnv) #test <<- test # This also works, but the above is more explicit. } (test.fun(1, test)) # v1 v2 #1 1 10 #2 1 10 #3 1 10 #4 2 0 #5 2 0 #6 2 0 

Persönlich würde ich return(test) und die Zuordnung außerhalb der function machen, aber ich bin mir nicht sicher, ob Sie das in Ihrer tatsächlichen Situation tun können.

 test.fun < - function (x, test) { test[test$v1==x,"v2"] <- 10 return(test) } test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0) (test <- test.fun(1, test)) # v1 v2 #1 1 10 #2 1 10 #3 1 10 #4 2 0 #5 2 0 #6 2 0 

Das Ändern des < - zu < < - in Ihrer function, tut auch den Trick, sehen Sie das R-Handbuch . Zitat von dieser Seite:

Die Operatoren < < - und - >> werden normalerweise nur in functionen verwendet und bewirken, dass in übergeordneten Umgebungen nach einer vorhandenen Definition der zugewiesenen Variablen gesucht wird. Wenn eine solche Variable gefunden wird (und ihre Bindung nicht gesperrt ist), wird ihr Wert neu definiert, andernfalls erfolgt die Zuweisung in der globalen Umgebung.

Ihr Code sollte dann sein:

 test < - data.frame(v1=c(rep(1,3),rep(2,3)),v2=0) test.fun <- function (x) { test[test$v1==x,"v2"] <<- 10 print(test) } test.fun(1) 

Es empfiehlt sich, globale Variablen in functionen nicht zu ändern, da dies unerwünschte Nebenwirkungen haben kann . Um dies in R zu vermeiden, ändern Änderungen an Objekten innerhalb einer function nur Kopien, die sich lokal in der environment dieser function befinden.

Wenn Sie wirklich den Test ändern möchten, müssen Sie den Rückgabewert der zu testenden function zuweisen (es wäre besser, die function mit einem expliziteren Rückgabewert zu schreiben,

  test < - test.fun(1) 

Oder wählen Sie die globale Umgebung aus, der Sie test.fun zuweisen test.fun .

 test.fun < - function (x) { test[test$v1==x,"v2"] <- 10 print(test) assign("test",test,.GlobalEnv) } 

Ich denke, das passiert aufgrund der verschiedenen environments , die ausgewertet werden. Ihre function kopiert den test von der globalen Umgebung in eine temporäre lokale Umgebung (die beim functionsaufruf erstellt wird), und dann wird der test nur in dieser lokalen Umgebung ausgewertet (dh geändert).

Du könntest dieses Problem überwinden, indem du die Super-Zuweisung verwendest < <- , aber das ist NICHT empfohlen und wird zu schrecklichen unvorhergesehenen Problemen führen (dein Computer fängt einen Virus auf, deine Freundin fängt an, dich zu betrügen, ...).

Im Allgemeinen ist die Lösung von Joshua Ulrich der Weg, um diese Art von Problemen zu lösen. Sie übergeben das ursprüngliche Objekt und geben es zurück. Beim functionsaufruf ordnen Sie das Ergebnis Ihrem ursprünglichen Objekt zu.

Sie könnten eine Ersatzfunktion schreiben. Dies ist eine function mit einem Namen, der mit ‘< -' endet und im Wesentlichen in ein:

foo = bar (foo)

Verpackung. Also in deinem Fall:

 > "setV2< -" = function (x,value,m){x[x$v1==m,"v2"]=value;return(x)} > test < - data.frame(v1=c(rep(1,3),rep(2,3)),v2=0) > setV2(test,1)=10 > test v1 v2 1 1 10 2 1 10 3 1 10 4 2 0 5 2 0 6 2 0 > setV2(test,2)=99 > test v1 v2 1 1 10 2 1 10 3 1 10 4 2 99 5 2 99 6 2 99 

Beachten Sie, dass Sie den functionsnamen bei der Erstellung angeben müssen oder dass R verwirrt wird.