<-
fa assegnazione nell'ambiente attuale.
Quando sei all'interno di una funzione, R crea un nuovo ambiente per te. Per impostazione predefinita include tutto, dall'ambiente in cui è stato creato, in modo da poter utilizzare anche quelle variabili, ma tutto ciò che si crea non verrà scritto nell'ambiente globale.
Nella maggior parte dei casi <<-
assegnerai a variabili già presenti nell'ambiente globale o creerai una variabile nell'ambiente globale anche se sei all'interno di una funzione. Tuttavia, non è così semplice. Ciò che fa è controllare l'ambiente padre per una variabile con il nome di interesse. Se non lo trova nel tuo ambiente genitore, va al genitore dell'ambiente genitore (al momento della creazione della funzione) e guarda lì. Continua verso l'alto nell'ambiente globale e se non viene trovato nell'ambiente globale assegnerà la variabile nell'ambiente globale.
Questo potrebbe illustrare cosa sta succedendo.
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
bar <- "in baz - before <<-"
bar <<- "in baz - after <<-"
print(bar)
}
print(bar)
baz()
print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"
La prima volta che stampiamo una barra che non abbiamo ancora chiamato, foo
quindi dovrebbe essere ancora globale - questo ha senso. La seconda volta che stampiamo è dentro foo
prima di chiamare, baz
quindi il valore "in foo" ha senso. Di seguito è dove vediamo cosa <<-
sta effettivamente facendo. Il prossimo valore stampato è "in baz - prima di << -" anche se l'istruzione print viene dopo <<-
. Questo perché <<-
non guarda nell'ambiente attuale (a meno che tu non sia nell'ambiente globale nel qual caso si <<-
comporta come <-
). Quindi all'interno del baz
valore di bar rimane come "in baz - prima di << -". Una volta che chiamiamo baz
la copia della barra al suo interno foo
viene cambiata in "in baz" ma, come possiamo vedere, il globale bar
è invariato.bar
che è definito all'interno di foo
è nell'ambiente padre quando l'abbiamo creato, baz
quindi questa è la prima copia di bar
ciò che <<-
vede e quindi la copia a cui assegna. Quindi <<-
non è solo l'assegnazione diretta all'ambiente globale.
<<-
è complicato e non consiglierei di usarlo se puoi evitarlo. Se vuoi veramente assegnare all'ambiente globale puoi usare la funzione di assegnazione e dirlo esplicitamente che vuoi assegnare a livello globale.
Ora cambio la <<-
in un'assegnazione e possiamo vedere quale effetto ha:
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
assign("bar", "in baz", envir = .GlobalEnv)
}
print(bar)
baz()
print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"
Quindi entrambe le volte che stampiamo la barra all'interno del foo
valore è "in pippo" anche dopo aver chiamato baz
. Questo perché assign
non bar
ho mai nemmeno considerato la copia di inside of foo perché gli abbiamo detto esattamente dove cercare. Tuttavia, questa volta il valore di bar nell'ambiente globale è stato modificato perché assegnato esplicitamente lì.
Ora hai anche chiesto informazioni sulla creazione di variabili locali e puoi farlo abbastanza facilmente anche senza creare una funzione ... Dobbiamo solo usare la local
funzione.
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"
globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env
...