<-
fait une affectation dans l'environnement actuel.
Lorsque vous êtes à l'intérieur d'une fonction, R crée un nouvel environnement pour vous. Par défaut, il inclut tout ce qui concerne l'environnement dans lequel il a été créé afin que vous puissiez également utiliser ces variables, mais tout ce que vous créez ne sera pas écrit dans l'environnement global.
Dans la plupart des cas <<-
, affectera des variables déjà dans l'environnement global ou créera une variable dans l'environnement global même si vous êtes à l'intérieur d'une fonction. Cependant, ce n'est pas aussi simple que cela. Il vérifie dans l'environnement parent une variable avec le nom qui vous intéresse. S'il ne le trouve pas dans votre environnement parent, il va au parent de l'environnement parent (au moment où la fonction a été créée) et y regarde. Il continue vers le haut dans l'environnement global et s'il n'est pas trouvé dans l'environnement global, il affectera la variable dans l'environnement global.
Cela pourrait illustrer ce qui se passe.
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 première fois que nous imprimons la barre, nous n'avons pas foo
encore appelé , donc elle devrait toujours être globale - cela a du sens. La deuxième fois que nous imprimons, il est à l'intérieur de foo
avant d'appeler, baz
donc la valeur "in foo" a du sens. Voici où nous voyons ce qui <<-
se passe réellement. La valeur suivante imprimée est "in baz - before << -" même si l'instruction print vient après le <<-
. C'est parce <<-
que ne regarde pas dans l'environnement actuel (sauf si vous êtes dans l'environnement global, auquel cas <<-
agit comme <-
). Donc à l'intérieur de baz
la valeur de bar reste comme "in baz - before << -". Une fois que nous appelons baz
la copie de bar à l'intérieur de foo
devient "in baz", mais comme nous pouvons le voir, le global bar
est inchangé.bar
qui est défini à l'intérieur de foo
est dans l'environnement parent lorsque nous avons créé baz
, c'est donc la première copie de ce bar
qui <<-
voit et donc la copie à laquelle il assigne. Il <<-
ne s'agit donc pas simplement d'assigner directement à l'environnement mondial.
<<-
est délicat et je ne recommanderais pas de l'utiliser si vous pouvez l'éviter. Si vous voulez vraiment assigner à l'environnement global, vous pouvez utiliser la fonction assign et lui dire explicitement que vous voulez assigner globalement.
Maintenant, je change le <<-
en une instruction assign et nous pouvons voir quel effet cela a:
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"
Ainsi, les deux fois que nous imprimons la barre à l'intérieur de foo
la valeur est "in foo" même après l'appel baz
. C'est parce que nous assign
n'avons même jamais considéré la copie de bar
inside of foo parce que nous lui avons dit exactement où chercher. Cependant, cette fois, la valeur de bar dans l'environnement global a été modifiée parce que nous l'avons explicitement assignée.
Maintenant, vous avez également posé des questions sur la création de variables locales et vous pouvez le faire assez facilement également sans créer de fonction ... Nous avons juste besoin d'utiliser la local
fonction.
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
,…