Chapitre 4 manipulation de données Programmation en R
Introduction # Dans le chapitre 2, nous avons présenté les principales structures de données ainsi que la manière de les manipuler. # Ici, nous allons présenter quelques concepts plus avancés.
La fonction « apply » # La fonction apply() permet d'appliquer une fonction spécifique à tous ou une partie des éléments d'un vecteur, d'une matrice ou d'un tableau. # Plus précisément, apply(x, d, f) prend comme arguments un vecteur, matrice ou tableau x, un vecteur de dimension d et une fonction f et retourne un vecteur, matrice ou tableau x' qui est le résultat de l'application de la fonction f à tous les éléments de la sous-structure x de dimension d. # Si x est une matrice, d = 1 signifie "toutes les lignes de x" et d = 2 signifie "toutes les colonnes de x".
La fonction « apply » # Matrice 5 x 4 de nombres tirés aléatoirement entre 1 et 100, avec répétition x <- matrix(sample(1:100, 20, rep = TRUE), 5, 4) x [,1] [,2] [,3] [,4] [1,] 33 84 52 62 [2,] 7 52 65 37 [3,] 5 97 23 17 [4,] 5 27 30 30 [5,] 20 71 86 33
La fonction « apply » # On calcule la somme des lignes et des colonnes sum_row <- apply(x, 1, sum) sum_row [1] 231 161 142 92 210 sum_col <- apply(x, 2, sum) sum_col [1] 70 331 256 179
La fonction « apply » # Pour les tableaux de dimension 3, c'est un peu plus subtil. # d = c(1,2) permet de considérer les "carottes horizontales". # d = c(1,3) permet de considérer les "carottes transversales". # d = c(2,3) permet de considérer les "carottes verticales".
Les fonctions « lapply » et « sapply » # La fonction lapply() permet d'appliquer une fonction spécifique à tous les éléments d'une liste ou toutes les colonnes d'un data frame (qui est en fait une liste de colonnes). # Plus précisément, dans le cas d’une liste lapply(l, f) prend comme arguments une liste l = (x1,...,xN) et une fonction f et retourne comme résultat la liste (f(x1),...,f(xN)). # Dans le cas d'un data frame d = (col1,...,colN), lapply(d, f) retourne la liste ou le data frame (f(col1),...,f(colN)). # La fonction sapply() est similaire, mais elle convertit le résultat de manière à retourner un vecteur, une matrice ou un tableau au lieu d'une liste ou d'un data frame.
Les fonctions « lapply » et « sapply » # Liste de trois vecteurs de 100 nombres tirés aléatoirement selon trois distributions différentes (uniforme, normale, beta). l <- list(uniform = runif(100, 0, 1), normal = rnorm(100, 1, 0.5), beta = rbeta(100, 1, 1)) l $uniform [1] 0.830450747 0.104512829 0.121752382 ... $normal [1] 1.000171488 0.904523695 1.009866931 $beta [1] 0.849801545 0.781608160 0.113795780
Les fonctions « lapply » et « sapply » # Avec lapply(), on applique la fonction moyenne aux trois éléments de l # on obtient une liste lapply(l, mean) $uniform [1] 0.4696207 $normal [1] 1.031039 $beta [1] 0.5253356
Les fonctions « lapply » et « sapply » # Avec sapply(), on obtient un vecteur, pas une liste... sapply(l, mean) uniform normal beta 0.4696207 1.0310385 0.5253356
Les fonctions « lapply » et « sapply » # Si la fonction considérée est multidimensionnelle, laplly() retourne toujours une liste. lapply(l, range) # range(x) retourne (min(x),max(x)) $uniform [1] 0.001760537 0.988299465 $normal [1] -1.050240 2.350391 $beta [1] 0.004136918 0.999715909
Les fonctions « lapply » et « sapply » # Et sapply() retourne une matrice. sapply(l, range) uniform normal beta [1,] 0.001760537 -1.050240 0.004136918 [2,] 0.988299465 2.350391 0.999715909
Les fonctions « lapply » et « sapply » # On applique ces fonctions à un data frame maintenant. # le data frame USArrests fournit des données de 1973 sur les types d'arrestations dans les 50 états des USA. head(USArrests) Murder Assault UrbanPop Rape Alabama 13.2 236 58 21.2 Alaska 10.0 263 48 44.5 Arizona 8.1 294 80 31.0 Arkansas 8.8 190 50 19.5 California 9.0 276 91 40.6 Colorado 7.9 204 78 38.7
Les fonctions « lapply » et « sapply » m1 <- lapply(USArrests, mean) m1 # le résulat est une liste $Murder [1] 7.788 $Assault [1] 170.76 $UrbanPop [1] 65.54 $Rape [1] 21.232 typeof(m1) [1] "list"
Les fonctions « lapply » et « sapply » m2 <- sapply(USArrests, mean) m2 Murder Assault UrbanPop Rape 7.788 170.760 65.540 21.232 typeof(m2) # le résultat est un vecteur [1] "double"
La fonction « mapply » # La fonction mapply() est la version multidimentionnelle de lapply() et sapply(). # Plus précisément, mapply(f, v1,...,vN) prend comme arguments une fonction f et une suite de vecteurs ou de listes v1,...,vN et applique la fonction successivement à tous les i-èmes éléments de v1,...,vN. # En d'autres termes, la fonction mapply() retourne (f(v1[1],...,vN[1]),...,f(v1[K],...,vN[K])) # Lorsque les v's ne sont pas de même taille, la fonction les "duplique" de manière adéquate.
La fonction « mapply » # La fonction paste concatène des éléments. mapply(paste, list("A", "B", "C"), list("a", "b", "c"), list(1, 2, 3)) [1] "A a 1" "B b 2" "C c 3" mapply(sum, c(1,2,3), c(10, 9, 8)) [1] 11 11 11
Exemple # On génère 5 courbes paraboliques (f(x) = x^2) altérées par un bruit normal de moyenne 0 et de sd 0.3. y1 <- seq(-3, 3, 0.1)^2 + rnorm(length(seq(-3, 3, 0.1)), 0, 0.3) y2 <- seq(-3, 3, 0.1)^2 + y3 <- seq(-3, 3, 0.1)^2 + y4 <- seq(-3, 3, 0.1)^2 + y5 <- seq(-3, 3, 0.1)^2 + # On crée un data frame avec les 5 courbes en colonnes courbes_df = data.frame(y1, y2, y3, y4, y5)
Exemple # On calcule la moyenne de chaque vecteur c(y1[i], y2[i], y3[i], y4[i], y5[i]). Pour cela: # on le convertit en matrice et on calcule la moyenne de ses lignes grâce à la fonction apply; # on obtient un vecteur. y_mean <- apply(as.matrix(courbes_df), 1, mean) typeof(y_mean) [1] "double"
Exemple # On ajoute y_mean comme nouvelle colonne de notre data frame. courbes_df <- cbind(courbes_df, y_mean) # on imprime le tout (librairie ggplot2)... library(ggplot2) ggplot(courbes_df, aes(x = seq(-3, 3, 0.1), y = value, color = variable)) + geom_point(aes(y = y1, col = "y1")) + geom_point(aes(y = y2, col = "y2")) + geom_point(aes(y = y3, col = "y3")) + geom_point(aes(y = y4, col = "y4")) + geom_point(aes(y = y5, col = "y5")) + geom_path(aes(y = y_mean, col = "mean"))
Exemple