<-
robi zadanie w obecnym środowisku.
Gdy znajdujesz się w funkcji R tworzy dla ciebie nowe środowisko. Domyślnie zawiera wszystko ze środowiska, w którym został utworzony, więc możesz używać tych zmiennych, ale wszystko, co stworzysz, nie zostanie zapisane w środowisku globalnym.
W większości przypadków <<-
przypisze zmienne znajdujące się już w środowisku globalnym lub utworzy zmienną w środowisku globalnym, nawet jeśli znajdujesz się w funkcji. Jednak nie jest to aż tak proste. To, co robi, sprawdza środowisko nadrzędne dla zmiennej o nazwie zainteresowania. Jeśli nie znajduje się w środowisku macierzystym, przechodzi do rodzica środowiska macierzystego (w momencie utworzenia funkcji) i tam się znajduje.Ciągnie się w górę do globalnego środowiska i jeśli nie zostanie znalezione w środowisku globalnym, przydzieli 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"
Pierwszy raz wydrukować poprzeczkę nie nazwali foo
jeszcze tak powinno być nadal globalny - to ma sens. Drugi raz wydrukujemy go wewnątrz foo
przed wywołaniem baz
, więc wartość "w foo" ma sens. Poniżej znajduje się, co widzimy, co faktycznie robi <<-
. Następna drukowana wartość to "in baz - before < < -" nawet jeśli instrukcja print pochodzi od <<-
. Dzieje się tak, ponieważ <<-
nie wygląda w bieżącym środowisku (chyba że znajdujesz się w środowisku globalnym, w którym to przypadku <<-
działa tak jak <-
). Więc wewnątrz baz
wartość paska pozostaje jako "w baz - przed < < -". Po wywołaniu baz
kopia paska wewnątrz foo
zostaje zmieniona na "w bazie", ale jak widać globalna bar
pozostaje niezmieniona. Dzieje się tak dlatego, że kopia bar
zdefiniowana wewnątrz foo
znajduje się w środowisku nadrzędnym, gdy utworzyliśmy baz
, więc jest to pierwsza kopia bar
, którą widzi <<-
, a tym samym kopia, do której przydzieli. Tak więc <<-
nie jest bezpośrednio przypisywane do środowiska globalnego.
<<-
jest skomplikowany i nie polecałbym go używać, jeśli można tego uniknąć. Jeśli naprawdę chcesz przypisać do środowiska globalnego, możesz użyć funkcji przypisania i wyraźnie powiedzieć, że chcesz ją przypisać globalnie.
Teraz mogę zmienić <<-
do przypisać oświadczenia i możemy zobaczyć, jaki efekt, który ma:
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 oba razy drukujemy bar wewnątrz foo
wartość jest „w foo”, nawet po wywołaniu baz
. To dlatego, że assign
nigdy nie brała pod uwagę kopii bar
wewnątrz foo, ponieważ powiedzieliśmy mu dokładnie, gdzie szukać. Jednak tym razem wartość słupka w środowisku globalnym została zmieniona, ponieważ została tam wyraźnie przypisana.
Teraz zapytałeś także o tworzenie zmiennych lokalnych i możesz to zrobić całkiem łatwo bez tworzenia funkcji ... Musimy tylko użyć funkcji local
.
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"
Kod do uruchomienia oprócz tych odpowiedzi: 'globalenv(); globalenv()%>% parent.env; globalenv()%>% parent.env%>% parent.env', ... – isomorphismes
@isomorphismes, 'Błąd: nie można znaleźć funkcji"%>% "'. Czy to inna forma przydziału? –
Odpowiedni wątek na R-help: [** Co oznacza operator "<< -"? **] (http://r.789695.n4.nabble.com/What-does-the-quot-lt- lt-quot-operator-mean-td3466657.html). – Henrik