<- realiza tareas en el entorno actual.
Cuando estás dentro de una función, R crea un nuevo entorno para ti. Por defecto, incluye todo desde el entorno en el que se creó para que pueda usar esas variables también, pero cualquier cosa nueva que cree no se escribirá en el entorno global.
En la mayoría de los casos, <<-se asignará a variables que ya están en el entorno global o creará una variable en el entorno global, incluso si está dentro de una función. Sin embargo, no es tan sencillo como eso. Lo que hace es verificar el entorno primario para una variable con el nombre de interés. Si no lo encuentra en su entorno principal, va al principal del entorno principal (en el momento en que se creó la función) y mira allí. Continúa hacia arriba al entorno global y, si no se encuentra en el entorno global, asignará la variable en el entorno global.
Esto podría ilustrar lo que está sucediendo.
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 primera vez que imprimimos la barra no hemos llamado footodavía, por lo que aún debería ser global, esto tiene sentido. La segunda vez que imprimimos está dentro de fooantes de llamar, bazpor lo que el valor "in foo" tiene sentido. Lo siguiente es donde vemos lo <<-que realmente está haciendo. El siguiente valor impreso es "en baz - antes << -" aunque la declaración de impresión viene después de <<-. Esto se debe a <<-que no se ve en el entorno actual (a menos que esté en el entorno global, en cuyo caso <<-actúa como tal <-). Entonces, dentro del bazvalor de la barra permanece como "en baz - antes de << -". Una vez que llamamos a bazla copia de la barra dentro de foose cambia a "in baz", pero como podemos ver, el global no barha cambiado.barque se define dentro de fooestá en el entorno principal cuando creamos, bazpor lo que esta es la primera copia de lo barque <<-ve y, por lo tanto, la copia a la que se asigna. Entonces, <<-no es solo asignar directamente al entorno global.
<<-es complicado y no recomendaría usarlo si puedes evitarlo. Si realmente desea asignar al entorno global, puede usar la función de asignación y decirle explícitamente que desea asignar globalmente.
Ahora cambio el <<-a una declaración de asignación y podemos ver qué efecto tiene:
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"
Entonces, las dos veces que imprimimos la barra dentro del foovalor está "in foo" incluso después de llamar baz. Esto se debe a que assignnunca consideró la copia del barinterior de foo porque le dijimos exactamente dónde buscar. Sin embargo, esta vez el valor de la barra en el entorno global cambió porque lo asignamos explícitamente allí.
Ahora también preguntó sobre la creación de variables locales y puede hacerlo con bastante facilidad sin crear una función ... Solo necesitamos usar la localfunción.
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...