2011-07-16 8 views
6

Il titolo è la domanda autonoma. Un esempio chiarisce che: ConsiderareAssegnazione di attributi di lista in un ambiente

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" 

mentre vorrei ottenere

g(x) 

$a 
[1] 1 

$b 
[1] "name" 

$d 
[1] FALSE 

Qualche osservazione. Sapevo cosa c'è di sbagliato nel mio esempio originale, ma lo sto usando per chiarire il mio obiettivo. Voglio evitare < < - e voglio che x sia cambiato nel frame principale.

Penso che la mia comprensione degli ambienti sia primitiva e ogni riferimento sia apprezzato.

+0

Cosa stai cercando di fare? Modifica variabili al di fuori del l'ambito attuale è in generale una pessima idea. – hadley

+0

Sto cercando di evitare di passare per valore un oggetto molto grande a una funzione che viene chiamata ripetutamente.La funzione modifica anche parte dell'oggetto.Utilizzare i globali statici non è raccomandato in nessuna lingua, ma a volte è utile – gappy

+0

Hai profilato il passaggio intorno all'oggetto e hai scoperto che si tratta di un problema? R non sta per copiare l'oggetto ect a meno che non lo modifichi, cosa che comunque stai facendo qui. Non è ovvio che questo approccio più complicato ti farà risparmiare tempo. – hadley

risposta

6

Il primo argomento su assign deve essere un nome di variabile, non la rappresentazione di carattere di un'espressione. Provare a sostituire f con:

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

noti che a, b e d sono componenti della lista, gli attributi non lista. Se volessimo aggiungere un attributo "d" a y in frame padre f s' avremmo fatto questo:

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

Si noti inoltre che a seconda di ciò che si desidera farlo può (o non può) essere meglio avere x essere un ambiente o un oggetto proto (dal pacchetto proto).

3

assign Il primo argomento deve essere un nome oggetto. L'utilizzo di assign equivale fondamentalmente all'esempio di conteggio alla fine della pagina di aiuto dell'assegnazione. Osservare:

> 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 

Questo può essere dove si desidera utilizzare "< < -" ma è generalmente considerato sospetto.

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

$b 
[1] "name" 

$d 
[1] FALSE 

Un ulteriore pensiero, offerto in assenza di qualsiasi obiettivo per questo esercizio e ignorando il termine "attributi", che Gabor ha sottolineato ha un significato specifico in R, ma non può essere stato il vostro obiettivo. Se tutto ciò che si desidera è l'output in modo che corrisponda alle specifiche, si raggiunge questo obiettivo, ma si noti che non si verifica alcuna alterazione di x nell'ambiente globale.

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

Il parent.frame per f è quello che potrebbe essere chiamato il "interno della g ma l'alterazione non si propaga verso l'ambiente globale.

+0

Non è che << - è sospetto - è un incarico al di fuori dell'ambiente locale. – hadley

Problemi correlati