Bonnes pratiques

Question 1

Guide de style

Reformatez le code R suivant en suivant le guide de style du tidyverse (seule la section « Syntax » du tidyverse style guide s’applique ici) : https://style.tidyverse.org/syntax.html

#Creation d'un objet
jeu.1<-matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
             nrow=2,
             ncol=5)
jeu.1[2,3]=NA#Ajout d'une valeur manquante
 #  Calculs :
MoyennesParColonne<-vector(mode='numeric' ,ncol(jeu.1))
for (i in 1 : ncol(jeu.1))
{
if(any(is.na(jeu.1)))
{
MoyennesParColonne[i] <- mean( jeu.1[,i], na.rm = TRUE );
}
else
{
    MoyennesParColonne[i] <- mean( jeu.1[,i] ); 
}
}
MoyennesParColonne

Solution

# Creation d'un objet
jeu_1 <- matrix(
  c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 
  nrow = 2, 
  ncol = 5
)
jeu_1[2, 3] <- NA  # Ajout d'une valeur manquante
# Calculs :
moyennes_par_colonne <- vector(mode = "numeric", length = ncol(jeu_1))
for (i in 1:ncol(jeu_1)) {
  if (any(is.na(jeu_1))) {
    moyennes_par_colonne[i] <- mean(jeu_1[, i], na.rm = TRUE)
  } else {
    moyennes_par_colonne[i] <- mean(jeu_1[, i]) 
  }
}
moyennes_par_colonne

Question 2

Opérateur « pipe »

2.1

Réécrivez les commandes suivantes avec l’opérateur %>%.

Ces commandes calculent toute la moyenne des observations de la variable Sepal.Length du jeu de données iris (package datasets), en restreignant le jeu de données aux observations pour lesquelles la valeur de la variable Species est "setosa".

# Commande 1
mean(iris[iris$Species == "setosa", "Sepal.Length"])

# Commande 2
mean(subset(iris, subset = Species == "setosa")$Sepal.Length)

# Commande 3
mean(
  subset(
    iris,
    subset = Species == "setosa", 
    select = Sepal.Length, 
    drop = TRUE
  )
)

Solution

library(magrittr)

# Commande 1
mean(iris[iris$Species == "setosa", "Sepal.Length"])
# Avec %>%
iris %>% '['(iris$Species == "setosa", "Sepal.Length") %>% mean
# ou encore mieux, utiliser le . pour spécifier iris, même dans le 2e argument
iris %>% '['(.$Species == "setosa", "Sepal.Length") %>% mean
# et il n'est pas nécessaire de passer par la fonction '['(), 
# nous pouvons nous en tenir à utiliser l'opérateur [ comme suit
iris %>% .[.$Species == "setosa", "Sepal.Length"] %>% mean

# Commande 2
mean(subset(iris, subset = Species == "setosa")$Sepal.Length)
# Avec %>%
iris %>% subset(subset = Species == "setosa") %>% '$'(Sepal.Length) %>% mean
# ou plus simplement
iris %>% subset(subset = Species == "setosa") %>% .$Sepal.Length %>% mean

# Commande 3
mean(
  subset(
    iris,
    subset = Species == "setosa", 
    select = Sepal.Length, 
    drop = TRUE
  )
)
# Avec %>%
iris %>% 
  subset(
    subset = Species == "setosa", 
    select = Sepal.Length, 
    drop = TRUE
  ) %>% 
  mean

2.2

L’opérateur %>% est souvent utilisé avec les packages du tidyverse tels que dplyr, tidyr et ggplot2. Voici un bout de code exploitant des fonctions du package dplyr pour calculer des statistiques descriptives agrégées selon les niveaux d’une variable catégorique. Ce code utilise encore les données iris.

library(dplyr)
iris_group <- group_by(iris, Species)
result <- summarise(
  iris_group,
  nbrObs = length(Sepal.Length),
  moySepal.Length = mean(Sepal.Length),
  varPetal.Width = mean(Petal.Width),
  cvPetal.Length = sd(Petal.Length) / mean(Petal.Length)
)

Réécrivez ce code en utilisant l’opérateur %>%.

Solution

library(dplyr)

iris_group <- group_by(iris, Species)
result <- summarise(
  iris_group,
  nbrObs = length(Sepal.Length),
  moySepal.Length = mean(Sepal.Length),
  varPetal.Width = var(Petal.Width),
  cvPetal.Length = sd(Petal.Length) / mean(Petal.Length)
)
result
## # A tibble: 3 x 5
##   Species    nbrObs moySepal.Length varPetal.Width cvPetal.Length
##   <fct>       <int>           <dbl>          <dbl>          <dbl>
## 1 setosa         50            5.01          0.0111         0.119 
## 2 versicolor     50            5.94          0.0391          0.110 
## 3 virginica      50            6.59          0.0754          0.0994


# Avec %>%
result2 <- iris %>% 
  group_by(Species) %>%
  summarise(
    nbrObs = length(Sepal.Length),
    moySepal.Length = mean(Sepal.Length),
    varPetal.Width = var(Petal.Width),
    cvPetal.Length = sd(Petal.Length) / mean(Petal.Length)
  )
result2
## # A tibble: 3 x 5
##   Species    nbrObs moySepal.Length varPetal.Width cvPetal.Length
##   <fct>       <int>           <dbl>          <dbl>          <dbl>
## 1 setosa         50            5.01          0.0111         0.119 
## 2 versicolor     50            5.94          0.0391          0.110 
## 3 virginica      50            6.59          0.0754          0.0994


# Nous pourrions aller encore plus loin
# (mais le code est moins lisible à mon avis).
result3 <- iris %>% 
  group_by(Species) %>%
  summarise(
    nbrObs = Sepal.Length %>% length,
    moySepal.Length = Sepal.Length %>% mean,
    varPetal.Width = Petal.Width %>% var,
    cvPetal.Length = Petal.Length %>% sd / Petal.Length %>% mean
  )
result3
## # A tibble: 3 x 5
##   Species    nbrObs moySepal.Length varPetal.Width cvPetal.Length
##   <fct>       <int>           <dbl>          <dbl>          <dbl>
## 1 setosa         50            5.01          0.0111         0.119 
## 2 versicolor     50            5.94          0.0391          0.110 
## 3 virginica      50            6.59          0.0754          0.0994