Rlang par Herr Lang
Source https://www.tidyverse.org/articles/2019/06/rlang-0-4-0/
La syntaxe Tidyverse permet d’utiliser les noms de colonnes du tableau de données comme des noms de variables globales tout le long du tuyau. Cette compréhension est perdue dans les définitions de fonction au moment où la variable est appelée dans la fonction. Pour récupérer cette possibilité, il faut présenter le nom de variable différemment dans la définition de fonction. L’ancienne solution consistait à utiliser des opérateurs peu clairs qui provenaient des méthodes de programmations internes. Le package rlang 4.0.4 propose un opérateur double accolade qui est équivalent. De la même façon, il est possible de passer les variables colonne arguments par leur nom sous forme de chaînes mais l’appel dans la fonction se fait par .data double crochet.
Dans le contexte d’un tuyau en mode commande, les colonnes “gender” et “mass” peuvent être appelées comme des variables :
## # A tibble: 5 x 2
## gender mass_maximum
## <chr> <dbl>
## 1 female 75
## 2 hermaphrodite 1358
## 3 male 159
## 4 none 140
## 5 <NA> 75
On définit une fonction qui effectue la même tâche que précédemment:
max_by <- function(data, var, clef) {
data %>%
group_by(clef) %>%
summarise(maximum = max(var, na.rm = TRUE))
}
starwars %>% max_by(mass, gender)
## Error: Column `clef` is unknown
La variable colonne n’est plus trouvée car dans l’exécution de la fonction, l’environnement de la variable (c’est-à-dire l’indication qu’il s’agit d’une colonne du tableau de données) est perdu. Pour conserver cette indication, on emploie la fonction enquo qui garde en mémoire l’environnement de la variable
max_by <- function(data, var, clef) {
data %>%
group_by(enquo(clef) )%>%
summarise(maximum = max(var, na.rm = TRUE))
}
starwars %>% max_by(mass, gender)
## Error: Column `enquo(clef)` is of unsupported type quoted call
Le message d’erreur a changé : la sortie de la fonction enquo n’est pas interprétable immédiatement par la fonction tidyverse. il faut utiliser l’opérateur !! pour présenter cette sortie aux fonctions tidyverse :
max_by <- function(data, var, clef) {
data %>%
group_by(!!enquo(clef))%>%
summarise(maximum = max(var, na.rm = TRUE))
}
starwars%>% max_by(mass, gender)
## Error: object 'mass' not found
La colonne mass n’est pas trouvée car nous n’avons pas encore corrigé cette partie du code. Le code enquo() est assez mystérieux pour un utilisateur; une petite visite dans l’aide confirme la difficulté : la fonction enquo ( et ses amis UQ, “!”, “!!”) est prévue pour écrire des fonctions internes. Utilisée sans maîtrise, elle génère des erreurs dificiles à interpréter. Le package rlang propose un opérateur compact double accolade qui remplace “!!enquo()”.
max_by <- function(data, var, clef) {
data %>%
group_by({{clef}}) %>%
summarise(maximum = max(!!enquo(var), na.rm = TRUE))
}
starwars %>% max_by(mass, gender)
## # A tibble: 5 x 2
## gender maximum
## <chr> <dbl>
## 1 female 75
## 2 hermaphrodite 1358
## 3 male 159
## 4 none 140
## 5 <NA> 75
Si les variables sont désignées par des chaînes, il faut utiliser l’opérateur double crochet avec un préfixe particulier “.data[[ ]]”. Le préfixe “.” n’est pas utilisé car il réfère à la structure de données initiale et pas à celle courante au moment de l’exécution de la fonction tidyverse.
max_by <- function(data, var, chaineclef) {
data %>%
group_by(.data[[chaineclef]]) %>%
summarise(maximum = max(.data[[var]], na.rm = TRUE))
}
starwars %>% max_by("height", "gender")
## # A tibble: 5 x 2
## gender maximum
## <chr> <int>
## 1 female 213
## 2 hermaphrodite 175
## 3 male 264
## 4 none 200
## 5 <NA> 167