R Language
Portée des variables
Recherche…
Remarques
Le piège le plus commun avec la portée se pose en parallélisation. Toutes les variables et fonctions doivent être transmises dans un nouvel environnement exécuté sur chaque thread.
Environnements et fonctions
Les variables déclarées à l'intérieur d'une fonction n'existent que si elles sont passées à l'intérieur de cette fonction.
x <- 1
foo <- function(x) {
y <- 3
z <- x + y
return(z)
}
y
Erreur: objet 'y' introuvable
Les variables passées dans une fonction puis réaffectées sont écrasées, mais uniquement à l'intérieur de la fonction .
foo <- function(x) {
x <- 2
y <- 3
z <- x + y
return(z)
}
foo(1)
x
5
1
Les variables affectées dans un environnement supérieur à une fonction existent dans cette fonction, sans être transmises.
foo <- function() {
y <- 3
z <- x + y
return(z)
}
foo()
4
Fonctions secondaires
Les fonctions appelées dans une fonction (sous-fonctions) doivent être définies dans cette fonction pour accéder aux variables définies dans l'environnement local sans être transmises.
Cela échoue:
bar <- function() {
z <- x + y
return(z)
}
foo <- function() {
y <- 3
z <- bar()
return(z)
}
foo()
Erreur dans bar (): objet 'y' introuvable
Cela marche:
foo <- function() {
bar <- function() {
z <- x + y
return(z)
}
y <- 3
z <- bar()
return(z)
}
foo()
4
Affectation globale
Les variables peuvent être affectées globalement à partir de n'importe quel environnement en utilisant <<-
. bar()
peut maintenant accéder à y
.
bar <- function() {
z <- x + y
return(z)
}
foo <- function() {
y <<- 3
z <- bar()
return(z)
}
foo()
4
L'affectation globale est fortement déconseillée. L'utilisation d'une fonction wrapper ou l'appel explicite de variables d'un autre environnement local est grandement préférable.
Affectation explicite d'environnements et de variables
Les environnements dans R peuvent être explicitement appelés et nommés. Les variables peuvent être explicitement assignées et appeler ou à partir de ces environnements.
Un environnement couramment créé est un environnement qui englobe package:base
ou un sous-environnement dans le package:base
.
e1 <- new.env(parent = baseenv())
e2 <- new.env(parent = e1)
Les variables peuvent être explicitement assignées et appeler ou à partir de ces environnements.
assign("a", 3, envir = e1)
get("a", envir = e1)
get("a", envir = e2)
3
3
Puisque e2
hérite de e1
, a
est 3
à 3
dans e1
et e2
. Cependant, l'attribution d' a
dans e2
ne change pas la valeur de a
dans e1
.
assign("a", 2, envir = e2)
get("a", envir = e2)
get("a", envir = e1)
3
2
Fonction de sortie
La fonction on.exit()
est pratique pour le nettoyage des variables si des variables globales doivent être affectées.
Certains paramètres, en particulier ceux des graphiques, ne peuvent être définis que globalement. Cette petite fonction est courante lors de la création de tracés plus spécialisés.
new_plot <- function(...) {
old_pars <- par(mar = c(5,4,4,2) + .1, mfrow = c(1,1))
on.exit(par(old_pars))
plot(...)
}
Forfaits et masquage
Les fonctions et objets des différents packages peuvent avoir le même nom. Le paquet chargé plus tard "masquera" le paquet précédent et un message d'avertissement sera imprimé. Lors de l'appel de la fonction par nom, la fonction du dernier paquet chargé sera exécutée. La fonction antérieure est accessible explicitement.
library(plyr)
library(dplyr)
Package joint: 'dplyr'
Les objets suivants sont masqués à partir de 'package: plyr':
arranger, compter, descendre, échec, id, muter, renommer, résumer, résumer
Les objets suivants sont masqués à partir de "package: stats":
filtre, retard
Les objets suivants sont masqués à partir de 'package: base':
intersection, setdiff, setequal, union
Lors de l'écriture du code, il est toujours préférable d'appeler les fonctions explicitement en utilisant package::function()
spécifiquement pour éviter ce problème.