2011-12-26 11 views
7

Qual è la differenza tra l'assegnazione di un valore a un nome in un ambiente e l'impostazione dell'ambiente di una variabile? Non riuscivo a capirlo dalla documentazione.Differenza tra assign (..., envir = ...) e environment (...) =

ad esempio:

MyTestFunc = function(x) 
{ 
    myVal = "abcde" 

    # what is this doing? why is myVal not in the global environment after 
    # this call? I see it adds an environment attribute to the variable, 
    # but what good is that? 
    environment(myVal) = globalenv() 

    assign("myVal" , myVal , envir = globalenv()) 

    # this seems to copy graphics:::rect to the current environment which seems 
    # to contradict the behavior of environment(myVal) above 
    environment(rect) = environment() 

    # this seems to do the same thing 
    assign("rect" , rect , envir = globalenv()) 
} 

# this prints out rect, but shows <environment: namespace: graphics>! 
rect 

risposta

6

La funzione di assegnazione si lega semplicemente un nome a un valore nell'ambiente specificato

?.. Ma la funzione di sostituzione dell'ambiente fa due cose: il suo scopo principale è quello di cambiare l'ambiente di una chiusura di una funzione, in cui il codice del corpo della funzione cerca le variabili e le funzioni globali.Normalmente, questo ambiente è quello in cui è stata definita la funzione (quindi se lo definisci al prompt userà globalenv). Come "bonus", assegna semplicemente l'attributo .Environment per altri tipi di oggetto.Questo è abbastanza inutile per la maggior parte degli oggetti, ma è utilizzato dalle formule.

La seconda cosa è che funziona come qualsiasi altra funzione di sostituzione: se il nome esiste nell'ambiente corrente, lo modifica direttamente, altrimenti crea una copia locale e la modifica. Quindi nel tuo caso, fa una copia locale della funzione rect e cambia il suo ambiente. La funzione originale rimane invariata.

# showing names replacement behavior 
f <- function() { 
    names(letters) <- LETTERS 
    letters # the local modified copy 
} 
f() # prints changed letters 
letters # unchanged 
+0

Grazie per la risposta super chiara! – SFun28

1

All'interno di una funzione che ha chiesto e giustiziati:

# what is this doing? why is myVal not in the global environment after this call? 
    # I see it adds an environment attribute to the variable, but what good is that? 
    environment(myVal) = globalenv() 

Quindi non ha davvero fare nulla all'oggetto myVal denominato "ABCDE" che era in funzione . Hai invece creato un nuovo ambiente denominato "abcede" all'interno dell'ambiente della funzione. È quindi eseguito:

assign("myVal" , myVal , envir = globalenv()) 

ha creato una variabile denominata "myVal" con il valore modalità carattere di "ABCDE" raccolte dall'ambiente funzione locale, e metterlo in l'ambiente globale. Ora ha un attributo chiamato ". Ambiente". Tuttavia, non è chiaro quali sono i tuoi obiettivi, dal momento che gli ambienti sono progettati per essere utilizzati per definire l'ambito delle funzioni . Assegnare un ambiente a un oggetto dati è solo strano. Le variabili sono in ambienti, ma non sembra essere utile per impostare l'ambiente di una variabile . Quindi penso che la risposta alla tua domanda: ... cosa buona è che "dovrebbe essere 'non è nulla di buono'

+0

Non riesco a riprodurre i commenti sull'ambiente (myVal) = globalenv(). Se ho creato un ambiente chiamato "abcde", allora dov'è quell'ambiente? Come posso accedervi? Sembra che ho appena aggiunto un attributo .Environment a myVal. E cosa spiega l'ambiente (rect) = environment()? I miei obiettivi sono semplicemente di capire meglio gli ambienti in modo da poter esplorare scenari più avanzati. – SFun28

+0

È stato aggiunto un attributo di ambiente a un oggetto carattere. Se si digita "abcde" nella console dopo aver eseguito una chiamata a MyTestFunc(), si ottiene un output che include: 'attr (,". Environment ") '. Non ho idea di come si possa accedere a quell'ambiente. Penso che questo rientri nell'acronimo DDT. –

+0

ah, capito! Ho aggiornato un po 'il mio codice di esempio. Potresti dare un'occhiata. Le chiamate assign() e environment() per rect fanno la stessa cosa? E perché la stampa retta mostra un ambiente diverso da globalenv? – SFun28