2011-07-16 12 views
6

Tytuł jest samodzielnym pytaniem. Przykładem wyjaśnia to: RozważmyPrzypisywanie atrybutów listy w środowisku

x=list(a=1, b="name") 
f <- function(){ 
    assign('y[["d"]]', FALSE, parent.frame()) 
} 
g <- function(y) {f(); print(y)} 

g(x) 

$a 
[1] 1 

$b 
[1] "name" 

natomiast chciałbym dostać

g(x) 

$a 
[1] 1 

$b 
[1] "name" 

$d 
[1] FALSE 

kilka uwag. Wiedziałem, co jest nie tak w moim oryginalnym przykładzie, ale używam go do wyjaśnienia mojego celu. Chcę uniknąć < < - i chcę zmienić x w ramce nadrzędnej.

Myślę, że moje rozumienie otoczenia jest prymitywne i wszelkie odniesienia są doceniane.

+0

Co chcesz zrobić? Modyfikacja zmiennych z zewnątrz obecny zakres jest ogólnie bardzo zły pomysł – hadley

+0

Próbuję uniknąć przekazywanie przez wartość bardzo duży obiekt do funkcji, która jest wywoływana wielokrotnie.Funkcja również modyfikuje część obiektu.Za pomocą statycznych globals nie jest zalecane w dowolnym języku, ale czasem jest użyteczny – gappy

+0

Czy profilowałeś omijanie obiektu i odkryłeś, że to problem? R nie będzie kopiować objektu Tak czy inaczej, chyba że ją zmodyfikujesz, i tak to robisz. Nie jest oczywiste, że to bardziej skomplikowane podejście pozwoli Ci zaoszczędzić czas. – hadley

Odpowiedz

6

Pierwszy argument dla assign musi być nazwą zmiennej, a nie reprezentacją znaku wyrażenia. Spróbuj wymienić f z:

f <- function() with(parent.frame(), y$d <- FALSE) 

Zauważ, że a, b i d są elementy list, nie lista atrybutów. Jeśli chcemy dodać atrybut "d" do y w f „s macierzystej ramy chcielibyśmy to zrobić:

f <- function() with(parent.frame(), attr(y, "d") <- FALSE) 

Należy również pamiętać, że w zależności od tego, co chcesz zrobić, to może (lub nie mogą) być lepiej mieć x być środowiskiem lub obiektem proto (z pakietu proto).

3

assign Pierwszy argument musi być nazwą obiektu. Twoje użycie numeru assign jest w zasadzie takie samo jak w przypadku kontrprzykładu na końcu przypisanej strony pomocy. Przestrzegać:

> x=list(a=1, b="name") 
> f <- function(){ 
+  assign('x["d"]', FALSE, parent.frame()) 
+ } 
> g <- function(y) {f(); print(`x["d"]`)} 
> g(x) 
[1] FALSE # a variable with the name `x["d"]` was created 

To może być tam, gdzie chcesz użyć „< < -” ale to ogólnie uznane podejrzanego.

> f <- function(){ 
+  x$d <<- FALSE 
+ } 
> g <- function(y) {f(); print(y)} 
> g(x) 
$a 
[1] 1 

$b 
[1] "name" 

$d 
[1] FALSE 

Kolejna myśl, oferowane w braku bramką dla tego ćwiczenia i ignorując termin „atrybuty”, który wskazał Gabor ma szczególne znaczenie w dziedzinie badań, ale może nie być twoim celem. Jeśli chcesz, aby dane wyjściowe pasowały do ​​twoich danych, osiągniesz ten cel, ale zauważysz, że nie zachodzi żadna zmiana x w globalnym środowisku.

> f <- function(){ 
+  assign('y', c(x, d=FALSE), parent.frame()) 
+ } 
> g <- function(y) {f(); print(y)} 
> g(x) 
$a 
[1] 1 

$b 
[1] "name" 

$d 
[1] FALSE 

> x # `x` is unchanged 
$a 
[1] 1 

$b 
[1] "name" 

parent.frame dla f jest to, co można by nazwać „Wnętrze g ale zmiana nie rozchodzą się w środowisku globalnym.

+0

To nie jest tak, że << - jest podejrzany - to każde zadanie poza lokalnym środowiskiem. – hadley

Powiązane problemy