Les objets de R, données et fonctions, sont nommés. Comme R est modulaire, avec la possibilité de lui ajouter un nombre indéterminé de packages, il est très probable que des conflits de nom apparaissent. Pour les régler, R dispose d’un système rigoureux de précédence des noms : le code s’exécute dans un environnement défini, héritant d’environnements parents. Organisation

R démarre dans un environnement vide. Chaque package chargé crée un environnement fils pour former une pile des environnements, dont chaque nouvel élément est appelé “fils” du précédent, qui est son “parent”.

La console se trouve dans l’environnement global, fils du dernier package chargé.

search()

## [1] ".GlobalEnv" "package:R6" "package:entropart" ## [4] "package:forcats" "package:stringr" "package:dplyr" ## [7] "package:purrr" "package:readr" "package:tidyr" ## [10] "package:tibble" "package:ggplot2" "package:tidyverse"

## [13] "package:kableExtra" "package:stats" "package:graphics" ## [16] "package:grDevices" "package:utils" "package:datasets" ## [19] "package:methods" "Autoloads" "package:base"

Le code d’une fonction appelée de la console s’exécute dans un environnement fils de l’environnement global :

# Environnement actuel

environment()

## <environment: R_GlobalEnv>

# La fonction f affiche son environnement

f <- function() environment()

# Affichage de l'environnement de la fonction

f()

## <environment: 0x7fb5a3224650>

# Environnement parent de celui de la fonction

parent.env(f())

## <environment: R_GlobalEnv> Recherche

La recherche des objets commence dans l’environnement local. S’il n’est pas trouvé, il est cherché dans l’environnement parent, puis dans le parent du parent, jusqu’à l’épuisement des environnements qui génère une erreur indiquant que l’objet n’a pas été trouvé.

Exemple :

# Variable q définie dans l'environnement global

q <- "GlobalEnv"

# Fonction définissant q dans son environnement

qLocalFonction <- function() { q <- "Fonction"

return(q) }

# La variable locale est retournée

qLocalFonction()

## [1] "Fonction"

# Fonction (mal écrite) utilisant une variable qu'elle # ne définit pas

qGlobalEnv <- function() { return(q)

}

# La variable de l'environnement global est retournée

qGlobalEnv()

# Suppression de cette variable

rm(q)

# La fonction base::q est retournée

qGlobalEnv()

## function (save = "default", status = 0, runLast = TRUE) ## .Internal(quit(save, status, runLast))

## <bytecode: 0x7fb5a622dcf0> ## <environment: namespace:base>

La variable q est définie dans l’environnement global. La fonction qLocalFonction définit sa propre variable q. L’appel de la fonction retourne la valeur locale de la fonction parce qu’elle se trouve dans l’environnement de la fonction.

La fonction qGlobalEnv retourne la variable q qu’elle ne définit pas localement. Elle la recherche donc dans son environnement parent et trouve la variable définie dans l’environnement global. En supprimant la variable de l’environnement global par rm(q), la fonction qGlobalEnv() parcourt la pile des environnements jusqu’à trouver un objet nommé q dans le package base, qui est la fonction permettant de quitter R. Elle aurait pu trouver un autre objet si un package contenant un objet qavait été chargé.

Pour éviter ce comportement erratique, une fonction ne doit jamais appeler un objet non défini dans son propre environnement.

Espaces de nom des packages

Il est temps de définir précisément ce que les packages rendent visible. Les packages contiennent des objets (fonctions et données) qu’ils exportent ou non. Ils sont habituellement appelés par la fonction library() qui effectue deux opérations :

• elle charge le package en mémoire, ce qui permet d’accéder à tous ses objets avec la syntaxe package::objet pour les objets exportés et package:::objet pour ceux qui ne le sont pas ;

• elle attache ensuite le package, ce qui place son environnement en haut de la pile.

Il est possible de détacher un package avec la fonction unloadNamespace() pour le retirer de la pile des environnements. Exemple :

# entropart chargé et attaché

library("entropart")

# Est-il attaché ?

isNamespaceLoaded("entropart")

# Pile des environnements

search()

## [1] ".GlobalEnv" "package:R6" "package:entropart" ## [4] "package:forcats" "package:stringr" "package:dplyr" ## [7] "package:purrr" "package:readr" "package:tidyr" ## [10] "package:tibble" "package:ggplot2" "package:tidyverse" ## [13] "package:kableExtra" "package:stats" "package:graphics" ## [16] "package:grDevices" "package:utils" "package:datasets" ## [19] "package:methods" "Autoloads" "package:base"

# Diversity(), une fonction exportée par entropart est # trouvée

Diversity(1, CheckArguments = FALSE)

## None

## 1

# Détacher et décharger entropart

unloadNamespace("entropart")

# Est-il attaché ?

isNamespaceLoaded("entropart")

## [1] FALSE

# Pile des environnements, sans entropart

search()

## [1] ".GlobalEnv" "package:R6" "package:forcats" ## [4] "package:stringr" "package:dplyr" "package:purrr" ## [7] "package:readr" "package:tidyr" "package:tibble" ## [10] "package:ggplot2" "package:tidyverse" "package:kableExtra" ## [13] "package:stats" "package:graphics" "package:grDevices" ## [16] "package:utils" "package:datasets" "package:methods" ## [19] "Autoloads" "package:base"

# Diversity() est introuvable

tryCatch(Diversity(1), error = function(e) print(e))

## <simpleError in Diversity(1): could not find function "Diversity">

# mais peut être appelée avec son nom complet. L'appel # exécute implicitement

entropart::Diversity(1, CheckArguments = FALSE)

## None

## 1

L’appel de entropart::Diversity() charge le package (c’est-à-dire, exécute implicitement loadNamespace("entropart")) mais ne l’attache pas.

En pratique, il faut limiter le nombre de package attachés pour limiter le risque d’appeler une fonction non désirée

homonyme de la fonction recherchée. Dans les cas critiques, il faut utiliser le nom complet de la fonction : package::fonction().

Un problème fréquent concerne la filter() de dplyr homonyme de celle de stats. Le package stats est habituellement chargé avant dplyr, un package du tidyverse. stats::filter() doit donc être appelée explicitement.

Cependant, le package dplyr ou tidyverse (qui attache tous les packages du tidyverse) peut être chargé systématiquement en créant un fichier .RProfile à la racine du projet contenant la commande :

library("tidyverse")

Dans ce cas, dplyr est chargé avant stats et c’est sa fonction qui est inaccessible.

In document MANDİBULANIN KALINLIK VE UZUNLUĞUNUN SAGİTTAL SPLİT RAMUS OSTEOTOMİSİNDE KULLANILAN FİKSASYON TÜRÜ VE KEMİK ÜZERİNDE OLUŞAN STRES İLE İLİŞKİSİNİN SONLU ELEMAN ANALİZİ İLE DEĞERLENDİRİLMESİ (Page 95-108)

Related documents