Comment ajouter des données sur un ggplot existant ? C’est une question que l’on me pose fréquemment, notamment lors des formations que j’anime sur ggplot2.
Pour aider un maximum d’entre vous, j’ai donc décidé d’écrire cet article pour vous montrer comment faire, assez simplement, avec deux approches différentes.
Dans l’exemple ci-dessous, je copie le data frame sportifs dans sportifs2, et je renomme freq_max en max_heart_rate pour que le nom de la variable soit le même que dans le dataset heart_disease.
La première consiste réellement à ajouter des données. La seconde approche consiste à d’abord construire un data frame global, en combinant les deux sources de données, et à les représenter ensemble à partir de ce jeu de données.
Ajouter directement des données sur un ggplot existant ?
Data
Pour illustrer cela, nous allons réaliser un scatterplot à l’aide des données heart_disease du package funModeling, afin d’étudier la relation entre la fréquence cardiaque maximale (max_heart_rate) et l’âge (age) des patients :
library(funModeling)
library(ggplot2)
ggplot(heart_disease, aes(x=age, y=max_heart_rate))+
geom_point(colour="blue")
Imaginons maintenant que nous avons un autre jeu de données, relatif à 50 sportifs âgés de 30 à 40 ans. Ce jeu de données comporte l’âge et la fréquence cardiaque maximale des sujets, mais également d’autres variables.
Et ce que nous souhaitons faire, c’est ajouter les données d’âge et de fréquence cardiaque maximale de ces sujets sur le graphique précédent.
Pour celles et ceux qui veulent reproduire l’exemple, vous pouvez simplement générer ces données en copiant-collant le code ci-dessous :
n <- 50
age <- round(runif(n, min=30, max=40),0)
freq_max <- round(220-age+rnorm(n,0,5),0)
taille <- round(rnorm(n,175,5),0)
poids <- round(rnorm(n, 75, 5),0)
sportifs <- data.frame(age,
freq_max,
taille,
poids)
head(sportifs)
## age freq_max taille poids
## 1 37 177 176 74
## 2 31 190 169 84
## 3 35 181 169 78
## 4 36 188 176 72
## 5 36 182 177 75
## 6 35 181 179 74
La solution, pour ajouter ces nouvelles données, consiste à ajouter une seconde couche geom, ici geom_point(), en :
- spécifiant le jeu de données comportant les data à ajouter (ici data=sportifs) dans l’argument data
- spécifiant les variables x et y dans la fonction aes(), en employant les noms dans le jeu de données à ajouter (ici aes(y=freq_max, x=age) ).
ggplot(heart_disease, aes(x=age, y=max_heart_rate))+
geom_point(colour="blue")+
geom_point(data=sportifs, aes(y=freq_max, x=age))
Vous pouvez modifier la couleur, la forme ou la taille en ajoutant les arguments correspondants dans la couche geom_point() :
ggplot(heart_disease, aes(x=age, y=max_heart_rate))+
geom_point(colour="blue")+
geom_point(data=sportifs, aes(y=freq_max, x=age), colour="red", shape=0, size=3)
Pour ajouter une courbe de tendance, j’ai l’impression qu’il est nécessaire que les variables x et y aient le même nom, dans les deux jeux de données. Dans tous les cas, ça peut être une bonne approche de veiller à ce que les variables soient nommées de façon identique.
sportifs2 <- sportifs
names(sportifs2)[2] <- "max_heart_rate"
names(sportifs2)
## [1] "age" "max_heart_rate" "taille" "poids"
Et ensuite, il ne reste plus qu’à ajouter une seconde couche geom_smooth() en spécifiant bien les données concernées dans l’argument data. Ici data=sportifs2
Combiner les data frame pour afficher les données des deux data frame
Le principe de cette seconde approche est de :
- créer une variable supplémentaire groupe (par exemple) dans chacun des deux data frame, afin d’identifier l’origine des données. Cette variable pourra nous servir ensuite, dans le graphique, pour contrôler la couleur des points et créer une légende.
- restreindre les deux data frame aux variables qui seront employées dans le graphique, afin de pouvoir assembler les lignes data frame
- combiner les deux data frame dans un seul data frame global
- réaliser le graphique avec ggplot2, en utilisant ce data frame global
Data
Pour que cela soit plus facile à comprendre, je vais utiliser deux petits jeux de données. Le premier, que je vais appeler table1, correspond aux 10 premières ligne du data frame heart-disease , avec seulement 4 variables : age, max_heart_rate, chest_pain,et oldpeak.
library(dplyr)
table1 <- heart_disease %>%
slice(1:10) %>%
select(age, max_heart_rate, chest_pain,oldpeak )
table1
## age max_heart_rate chest_pain oldpeak
## 1 63 150 1 2.3
## 2 67 108 4 1.5
## 3 67 129 4 2.6
## 4 37 187 3 3.5
## 5 41 172 2 1.4
## 6 56 178 2 0.8
## 7 62 160 4 3.6
## 8 57 163 4 0.6
## 9 63 147 4 1.4
## 10 53 155 4 3.1
Le second jeu de données, que je vais appeler table2, correspond aux 10 premières lignes du data frame sportifs , avec ses 4 variables : age , freq_max, taille et poids.
table2 <- sportifs %>%
slice(1:10)
table2
## age freq_max taille poids
## 1 37 177 176 74
## 2 31 190 169 84
## 3 35 181 169 78
## 4 36 188 176 72
## 5 36 182 177 75
## 6 35 181 179 74
## 7 34 184 178 69
## 8 37 190 174 73
## 9 40 175 171 74
## 10 31 197 174 71
Créer les variables groupe
# ajout de la variable groupe dans les data heart disease
table1 <- table1 %>%
mutate(groupe="table1")
table1
## age max_heart_rate chest_pain oldpeak groupe
## 1 63 150 1 2.3 table1
## 2 67 108 4 1.5 table1
## 3 67 129 4 2.6 table1
## 4 37 187 3 3.5 table1
## 5 41 172 2 1.4 table1
## 6 56 178 2 0.8 table1
## 7 62 160 4 3.6 table1
## 8 57 163 4 0.6 table1
## 9 63 147 4 1.4 table1
## 10 53 155 4 3.1 table1
# ajout de la variable groupe dans les data sportifs
table2 <- table2 %>%
mutate(groupe="table2")
table2
## age freq_max taille poids groupe
## 1 37 177 176 74 table2
## 2 31 190 169 84 table2
## 3 35 181 169 78 table2
## 4 36 188 176 72 table2
## 5 36 182 177 75 table2
## 6 35 181 179 74 table2
## 7 34 184 178 69 table2
## 8 37 190 174 73 table2
## 9 40 175 171 74 table2
## 10 31 197 174 71 table2
Restreindre les data frame aux variables communes
Pour cela, nous pouvons commencer par renommer la variable freq_max de la table 2, en max_heart_rate afin d’être identique au nom de la table1.
table2 <- table2 %>%
rename(max_heart_rate=freq_max)
table2
## age max_heart_rate taille poids groupe
## 1 37 177 176 74 table2
## 2 31 190 169 84 table2
## 3 35 181 169 78 table2
## 4 36 188 176 72 table2
## 5 36 182 177 75 table2
## 6 35 181 179 74 table2
## 7 34 184 178 69 table2
## 8 37 190 174 73 table2
## 9 40 175 171 74 table2
## 10 31 197 174 71 table2
Nous allons ensuite restreindre les variables par sélection :
table1s <- table1 %>%
select(age, max_heart_rate, groupe)
table1s
## age max_heart_rate groupe
## 1 63 150 table1
## 2 67 108 table1
## 3 67 129 table1
## 4 37 187 table1
## 5 41 172 table1
## 6 56 178 table1
## 7 62 160 table1
## 8 57 163 table1
## 9 63 147 table1
## 10 53 155 table1
table2s <- table2 %>%
select(age, max_heart_rate, groupe)
table2s
## age max_heart_rate groupe
## 1 37 177 table2
## 2 31 190 table2
## 3 35 181 table2
## 4 36 188 table2
## 5 36 182 table2
## 6 35 181 table2
## 7 34 184 table2
## 8 37 190 table2
## 9 40 175 table2
## 10 31 197 table2
Combiner les deux data frame
table_all <- bind_rows(table1s, table2s)
table_all
## age max_heart_rate groupe
## 1 63 150 table1
## 2 67 108 table1
## 3 67 129 table1
## 4 37 187 table1
## 5 41 172 table1
## 6 56 178 table1
## 7 62 160 table1
## 8 57 163 table1
## 9 63 147 table1
## 10 53 155 table1
## 11 37 177 table2
## 12 31 190 table2
## 13 35 181 table2
## 14 36 188 table2
## 15 36 182 table2
## 16 35 181 table2
## 17 34 184 table2
## 18 37 190 table2
## 19 40 175 table2
## 20 31 197 table2
Les variables peuvent être dans un ordre différent :
table2s2 <- table2s %>%
relocate(age,.after = last_col())
table2s2
## max_heart_rate groupe age
## 1 177 table2 37
## 2 190 table2 31
## 3 181 table2 35
## 4 188 table2 36
## 5 182 table2 36
## 6 181 table2 35
## 7 184 table2 34
## 8 190 table2 37
## 9 175 table2 40
## 10 197 table2 31
table_all2 <- bind_rows(table1s, table2s2)
table_all2
## age max_heart_rate groupe
## 1 63 150 table1
## 2 67 108 table1
## 3 67 129 table1
## 4 37 187 table1
## 5 41 172 table1
## 6 56 178 table1
## 7 62 160 table1
## 8 57 163 table1
## 9 63 147 table1
## 10 53 155 table1
## 11 37 177 table2
## 12 31 190 table2
## 13 35 181 table2
## 14 36 188 table2
## 15 36 182 table2
## 16 35 181 table2
## 17 34 184 table2
## 18 37 190 table2
## 19 40 175 table2
## 20 31 197 table2
Réalisation du graphique
Par exemple :
ggplot(table_all, aes(x=age, y=max_heart_rate, colour=groupe, shape=groupe))+
geom_point(show.legend=FALSE)+
geom_smooth(method="lm")+
scale_colour_manual(values=c("red", "blue"))+
scale_shape_manual(values=c(1,8))+
labs(colour="Origine")
J’espère que ce court article répondra à vos attentes, et vous aidera à ajouter des données sur vos ggplot.
Si vous souhaitez apprendre à utiliser ggplot2 en pratique courante, et devenir autonome, j’animerai une journée de formation le 22 avril (4 places sont disponibles)
Et si vous souhaitez apprendre à utiliser ggplot, mais aussi à manipuler efficacement vos données (tableaux, variables de date et d’heures, variables qualitatives, chaines de caractères) et à réaliser des documents reproductibles automatisés et dynamiques avec R markdown, vous pouvez me rejoindre sur la prochaine session de la formation R pour la data analyse sur 3 jours, du 13 au 14 avril