tutorial - superponer graficas en r
Variables globales y locales en R (3)
Soy un novato para R, y estoy bastante confundido con el uso de variables locales y globales en R.
Leí algunas publicaciones en Internet que dicen que si uso =
o <-
asignaré la variable en el entorno actual, y con <<-
puedo acceder a una variable global cuando estoy dentro de una función.
Sin embargo, como recuerdo en C ++, surgen variables locales cada vez que declaras una variable entre paréntesis {}
, entonces me pregunto si esto es lo mismo para R? ¿O es solo para funciones en R que tenemos el concepto de variables locales?
Hice un pequeño experimento, lo que parece sugerir que solo los corchetes no son suficientes, ¿estoy obteniendo algo mal?
{
x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
Las variables declaradas dentro de una función son locales para esa función. Por ejemplo:
foo <- function() {
bar <- 1
}
foo()
bar
da el siguiente error: Error: object ''bar'' not found
.
Si desea hacer que bar
una variable global, debe hacer:
foo <- function() {
bar <<- 1
}
foo()
bar
En este caso bar
se puede acceder a la bar
desde fuera de la función.
Sin embargo, a diferencia de C, C ++ o muchos otros lenguajes, los corchetes no determinan el alcance de las variables. Por ejemplo, en el siguiente fragmento de código:
if (x > 10) {
y <- 0
}
else {
y <- 1
}
y
sigue siendo accesible después de la declaración if-else
.
Como bien dices, también puedes crear entornos anidados. Puede echar un vistazo a estos dos enlaces para comprender cómo usarlos:
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/environment.html
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/get.html
Aquí tienes un pequeño ejemplo:
test.env <- new.env()
assign(''var'', 100, envir=test.env)
# or simply
test.env$var <- 100
get(''var'') # var cannot be found since it is not defined in this environment
get(''var'', envir=test.env) # now it can be found
Un poco más en la misma línea
attrs <- {}
attrs.a <- 1
f <- function(d) {
attrs.a <- d
}
f(20)
print(attrs.a)
imprimirá "1"
attrs <- {}
attrs.a <- 1
f <- function(d) {
attrs.a <<- d
}
f(20)
print(attrs.a)
Se imprimirá "20"
<-
hace la asignación 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 fue creado 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 <<-
asignará las 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 principal para una variable con el nombre de interés. Si no lo encuentra en su entorno primario, va al padre del entorno principal (en el momento en que se creó la función) y se ve allí. Continúa hacia arriba en el 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 a foo
por lo que aún debería ser global; esto tiene sentido. La segunda vez que imprimimos está dentro de foo
antes de llamar a baz
así que el valor "in foo" tiene sentido. A continuación es donde vemos qué <<-
está realmente haciendo. El siguiente valor impreso es "in baz - before << -" aunque la instrucción print viene después de <<-
. Esto se debe a que <<-
no se ve en el entorno actual (a menos que se encuentre en el entorno global, en cuyo caso <<-
actúa como <-
). Entonces, dentro de baz
el valor de la barra permanece como "en baz - antes << -". Una vez que llamamos baz
la copia de la barra dentro de foo
cambia a "in baz", pero como podemos ver, la bar
global no cambia. Esto se debe a que la copia de la bar
que se define dentro de foo
está en el entorno principal cuando creamos baz
así que esta es la primera copia de la bar
que <<-
ve y, por lo tanto, la copia que 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 e indicar 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 de foo
el valor es "in foo" incluso después de llamar a baz
. Esto es porque assign
nunca consideró la copia de la bar
dentro de foo porque le dijimos exactamente dónde mirar. Sin embargo, esta vez el valor de la barra en el entorno global se modificó porque allí se asignó explícitamente.
Ahora también preguntaste sobre la creación de variables locales y también puedes hacerlo con bastante facilidad sin crear una función ... Solo necesitamos usar la función local
.
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"