<-
wykonuje przypisanie w obecnym środowisku.
Kiedy jesteś wewnątrz funkcji, R tworzy dla ciebie nowe środowisko. Domyślnie zawiera wszystko ze środowiska, w którym został utworzony, więc możesz również użyć tych zmiennych, ale wszystko, co stworzysz, nie zostanie zapisane w środowisku globalnym.
W większości przypadków <<-
przypisze zmienne już w środowisku globalnym lub utworzy zmienną w środowisku globalnym, nawet jeśli jesteś wewnątrz funkcji. Jednak nie jest to takie proste. To, co robi, to sprawdzenie środowiska nadrzędnego pod kątem zmiennej o nazwie, która nas interesuje. Jeśli nie znajdzie go w twoim środowisku nadrzędnym, przechodzi do środowiska nadrzędnego środowiska nadrzędnego (w momencie tworzenia funkcji) i tam szuka. Kontynuuje w górę do środowiska globalnego i jeśli nie zostanie znaleziony w środowisku globalnym, przypisze zmienną w środowisku globalnym.
To może zilustrować, co się dzieje.
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"
Gdy po raz pierwszy drukujemy pasek, którego jeszcze nie foo
wywołaliśmy, powinien nadal być globalny - to ma sens. Za drugim razem, gdy drukujemy, znajduje się w środku foo
przed wywołaniem, baz
więc wartość „in foo” ma sens. Poniżej znajduje się, gdzie widzimy, co <<-
faktycznie robi. Następna wypisywana wartość to "in baz - przed << -", mimo że instrukcja print występuje po <<-
. Dzieje się tak, ponieważ <<-
nie wygląda w obecnym środowisku (chyba że jesteś w środowisku globalnym, w którym to przypadku <<-
zachowuje się tak <-
). Zatem wewnątrz baz
wartości bar pozostaje „in baz - przed << -”. Kiedy już wywołamy baz
kopię wewnątrz bara, foo
zostanie zmieniona na "in baz", ale jak widzimy, globalny bar
pozostaje niezmieniony.bar
która jest zdefiniowana wewnątrz programu, foo
znajduje się w środowisku nadrzędnym podczas tworzenia, baz
więc jest to pierwsza kopia tego, bar
która <<-
widzi, a tym samym kopia, do której przypisuje. Nie <<-
jest to więc tylko bezpośrednie przypisywanie do środowiska globalnego.
<<-
jest trudna i nie polecałbym jej używać, jeśli możesz jej uniknąć. Jeśli naprawdę chcesz przypisać do środowiska globalnego, możesz użyć funkcji przypisania i wyraźnie powiedzieć, że chcesz przypisać globalnie.
Teraz zmieniam instrukcję <<-
na przypisaną i możemy zobaczyć, jaki to ma skutek:
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"
Więc za każdym razem wypisujemy bar wewnątrz foo
wartości "in foo" nawet po wywołaniu baz
. Dzieje się tak, ponieważ assign
nigdy nawet nie rozważaliśmy kopii bar
wnętrza foo, ponieważ powiedzieliśmy mu dokładnie, gdzie szukać. Jednak tym razem wartość bar w środowisku globalnym została zmieniona, ponieważ wyraźnie tam przypisaliśmy.
Teraz zapytałeś również o tworzenie zmiennych lokalnych i możesz to zrobić dość łatwo bez tworzenia funkcji ... Musimy tylko użyć local
funkcji.
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
,…