Comment utiliser ggplot dans une boucle ou dans une fonction ?
ggplot()
est la fonction de base du package ggplot2
, qui est le package incontournable pour réaliser des représentations graphiques avec R. ggplot2
est extrêmement populaire car il permet de réaliser une multitude de visualisations, de façon rapide et esthétique.
La réalisation de plots avec ce package nécessite un petit apprentissage pour en comprendre le principe, mais ne pose pas de problème particulier, en pratique courante.
En revanche, lorsqu’on souhaite utiliser la fonction ggplot
au sein d’une boucle, pour réaliser un graphique de façon itérative par exemple, ou encore lorsqu’on souhaite l’intégrer au sein d’une autre fonction, cela est généralement plus délicat.
La solution est en réalité très simple puisqu’elle consiste à utiliser l’argument aes_string
à la place de l’argument aes
lorsqu’on fait appel à la fonction ggplot
!
Dans ce post, je vais donc vous montrer concrètement comment utiliser la fonction ggplot
à l’intérieur d’une boucle for
, puis au sein d’une fonction.
Si vous faites partis des rares utilisateurs de R qui n’utilisent pas encore ggplot2
, vous pourrez trouver deux introductions à ce package, en français, ici et là
Table des matières
Définition du problème
Utilisation courante de ggplot2
Imaginons que je souhaite évaluer la linéarité de la relation entre deux variables. Pour cela, je peux réaliser un scatterplot avec ggplot2
et ajouter une droite de régression linéaire, ainsi qu’une courbe loess, par exemple. Comme cela :
Pour réaliser ce plot, j’ai utilisé les données iris
, restreintes à l’espèce “setosa”. Je les ai obtenues avec les commandes suivantes :
setosa <- iris %>%
dplyr::filter(Species=="setosa") %>%
select(-Species)
Le jeu de données “setosa” comporte quatre variables :
head(setosa)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3.0 1.4 0.2
## 3 4.7 3.2 1.3 0.2
## 4 4.6 3.1 1.5 0.2
## 5 5.0 3.6 1.4 0.2
## 6 5.4 3.9 1.7 0.4
J’ai ensuite construit le scatter plot de la variable “Sepal.Length” en fonction de la variable “Sepal.Width”. La fonction ggplot
permettant alors de définir :
- le data.frame (tableau de données) qui contient les données, à
l’aide de l’argumentdata
- les variables à représenter à l’aide de l’argument :
aes(y=Sepal.Length,x=Sepal.Width)
Le type “scatterplot” est ensuite défini à l’aide de la fonction geom_point
. Et les fonctions geom_smooth
permettent de tracer la courbe loess, puis la droite de régression. Au final les commandes sont les suivantes :
ggplot(setosa, aes(y=Sepal.Length,x=Sepal.Width)) +
geom_point() +
geom_smooth(method=loess, se=FALSE) +
geom_smooth(method=lm, colour="red", fill="red", alpha=0.25)
Utilisation automatisée de ggplot2
Imaginons à présent que je souhaite créer, de façon automatisée, un scatter plot de la variable “Sepal.Length”, en fonction de chacune des trois autres variables du jeu de données. Autrement dit, trois scatterplots, avec chacun une variable prédictive différente “Sepal.Width”, “Petal.Length” et “Petal. Width”.
Je pourrais biensur passer le jeu de données en format “long” à l’aide de la fonction gather
.
setosa_long <- setosa %>%
gather(variable, value, -Sepal.Length)
head(setosa_long)
## Sepal.Length variable value
## 1 5.1 Sepal.Width 3.5
## 2 4.9 Sepal.Width 3.0
## 3 4.7 Sepal.Width 3.2
## 4 4.6 Sepal.Width 3.1
## 5 5.0 Sepal.Width 3.6
## 6 5.4 Sepal.Width 3.9
Puis utiliser la fonction facet_wrap
.
ggplot(setosa_long, aes(y=Sepal.Length, x=value))+
geom_point() +
geom_smooth(method=loess, se=FALSE) +
geom_smooth(method=lm, colour="red", fill="red", alpha=0.25)+
facet_wrap(~variable, scales="free")
Cette solution peut être adaptée lorsque le nombre de variables explicatives (celles que l’on va représenter sur l’axe des x) est faible. En revanche lorsque ce nombre est important cette solution conduit à des plots de petite taille et donc à une lisibilité réduite.
Imaginons donc que je souhaite créer ces 3 plots de façon distincte.
Deux solutions sont alors possibles :
- utiliser directement la fonction
ggplot
dans une boucle - construire une fonction qui emploie la fonction
ggplot
, et
l’intégrer dans une boucle.
Je vais donc vous montrer comment réaliser concrètement ces deux solutions.
Utiliser ggplot dans une boucle (for par exemple)
Le problème ici, dans la boucle, c’est de parvenir à changer itérativement la variable explicative (celle qui est représentée sur l’axe des x). Pour cela, on doit impérativement utiliser l’argumentaes_string
car contrairement à l’argumentaes
, il peut intégrer des chaines de caractères. Les variables explicatives sont alors fournies à l’argument aes_string
en utilisant la fonctioncolnames(data.frame)[i]
.
for(i in 2:ncol(setosa)) # on commence à 2 car la première variable est la variable réponse
{
p <- ggplot(setosa) +
geom_point(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]))+
geom_smooth(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]),method=loess, se=FALSE)+
geom_smooth(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]),method=lm, colour="red", fill="red", alpha=0.25) +
theme_classic ()
print(p)
}
Et si vous voulez sauvegarder automatiquement ces plots, vous pouvez utiliser les commandes suivantes :
for(i in 2:ncol(setosa))
{
jpeg(paste(i, "jpeg", sep = "."), width = 15, height =12, units="cm", quality=75, res=300)
p <- ggplot(setosa) +
geom_point(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]))+
geom_smooth(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]),method=loess, se=FALSE)+
geom_smooth(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]),method=lm, colour="red", fill="red", alpha=0.25) +
theme_classic ()
print(p)
dev.off()
}
Utiliser ggplot dans une fonction
Une autre façon de faire, pour créer ces 3 plots, peut consister à créer une fonction plot, en utilisant ici encore l’argument aes_string
my_plot <- function (df, x, y)
{
ggplot(df, aes_string(x=x, y=y))+
geom_point()+
geom_smooth( method=loess, se=FALSE)+
geom_smooth(method=lm, colour="red", fill="red", alpha=0.25) +
theme_classic ()
}
Qui s’utilise comme ceci :
my_plot(setosa, "Sepal.Width", "Sepal.Length")
Ensuite, cette fonction peut être intégrée dans une boucle for
, comme cela par exemple :
for(i in 2:ncol(setosa)){
p <- my_plot(setosa, names(setosa)[i], "Sepal.Length")
print(p)
}
Et là encore, pour sauvegarder les plots automatiquement dans des fichiers jpeg, vous utiliser les lignes suivantes:
for(i in 2:ncol(setosa)){
jpeg(paste(names(setosa)[i], "jpeg", sep = "."), width = 15, height =12, units="cm", quality=75, res=300)
p <- my_plot(setosa, names(setosa)[i], "Sepal.Length")
print(p)
dev.off()
}
Voilà ! J’espère que cet article vous évitera de perdre inutilement du temps à la recherche d’une solution, et qu’il vous permettra de réaliser plus facilement vos plots de façon automatisée avec ggplot2
.
Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir ce blog en faisant un don sur sa page Tipeee
Crédits photos : jambulboy
Bonjour,
Merci pour ce super sujet.
Je n’arrive pas à afficher plusieurs graphiques en même temps avec aes-string. Est-ce qu’il y a des packages à installer pour que plusieurs graphiques s’affichent sur la même fenêtre ?
Par exemple pour la commande :
for(i in 2:ncol(setosa))
{
p <- ggplot(setosa)
geom_point(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]))
geom_smooth(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]),method=loess, se=FALSE)
geom_smooth(aes_string(y = "Sepal.Length", x = colnames(setosa)[i]),method=lm, colour="red", fill="red", alpha=0.25)
theme_classic ()
print(p)
}
J'obtient ce message :
Warning messages:
1: In simpleLoess(y, x, w, span, degree = degree, parametric = parametric, :
pseudoinverse used at 0.0975
2: In simpleLoess(y, x, w, span, degree = degree, parametric = parametric, :
neighborhood radius 0.2025
3: In simpleLoess(y, x, w, span, degree = degree, parametric = parametric, :
reciprocal condition number 2.8298e-016
4: In simpleLoess(y, x, w, span, degree = degree, parametric = parametric, :
There are other near singularities as well. 0.01
Seul le deuxième graphique s'affiche. Merci d'avance pour l'aide. Et merci aussi pour tous les autres articles 🙂
Bonsoir Marc,
non il n’est pas nécessaire d’installer d’autres packages. Normalement vous devriez retrouver les 3 plots réalisés successivement dans la fenêtre des plots. Pour comprendre ce qui se passe vous pouvez initialiser i à 2 puis copier les coller les lignes de commandes dans la console, puis passer i à 3 et recommencer, etc… Les warnings concernent les courbes LOESS, ils ne sont pas très importants. Bonne continuation.
Bonjour,
Tout d’abord merci pour votre très bon tuto.
Une petite question : comment et-il possible d’ajouter sur chaque graphique le coefficient r2 (r-squarred) ainsi que la p-value ?
Merci d’avance
Bonjour Amandine, vous trouverez une piste dans le chapitre 7.8.3 du livre https://r-graphics.org/chapter-annotate
Bonjour,
Un énorme merci pour vos explications qui sont toujours très claires et qui m’ont, encore une fois, fait gagner un temps fou!
Karine
Bonjour est t’il possible de les afficher tous en même temps via une fonction plot_grid par exemple?
merci beaucoup
Ninon
Bonjour,
je n’ai pas essayé, mais je pense que ça doit fonctionner. N’hesitez pas à nous partager votre code, si c’est le cas !
Bonne continuation.