ggplot data + abline model

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Tomas leon
Messages : 22
Enregistré le : 09 Jan 2018, 16:12

ggplot data + abline model

Messagepar Tomas leon » 14 Mai 2018, 16:27

Bonjour à tous,

J'ai une question technique s'il vous plait

J'ai fait un modèle que je veux confronter visuellement avec mes données. Il s'agit d'une régression multiple de type :
Réponse = a0 + a1 V1 + a2 v2 + a3 V3 + ep. J'ai fait une estimation des paramètres du modèle a0, a1, a2, a3 et ep avec leurs IC.

J'aimerais faire un graphique de 3 panels, avec pour chaque panel la réponse en ordonnée et chaque variable en abscisse. J'aimerais superposer sur chacun des panels une droite avec la valeur de la pente associée à la variable + son IC de part et d'autre par transparence. (par exemple pour "a1" j'ai médiane : 1.19, IC 90% = 0.62;1.76)

L'on m'a conseillé d'utiliser ggplot pour faire cela, mais je ne vois pas du tout comment faire. Pouvez-vous m'aider s'il vous plait ?

Merci à tous !

Pierre-Yves Berrard
Messages : 449
Enregistré le : 12 Jan 2016, 23:30

Re: ggplot data + abline model

Messagepar Pierre-Yves Berrard » 15 Mai 2018, 10:25

Si je comprends bien, tu as 4 variables : V1, V2, V3 et REPONSE.

Pour que les données soient utilisables par ggplot2, il faut commencer par créer une table avec les variables :
  • VARIABLE (qui prendra les modalités "V1", "V2" et "V3")
  • VALEUR
  • REPONSE
Cela peut se faire facilement avec la fonction gather du package tidyr.

Ensuite, il faudra faire un nuage de points croisant VALEUR et REPONSE avec un facet_wrap (ce que tu appelles panel je suppose) sur VARIABLE.
PY

Logez Maxime
Messages : 2797
Enregistré le : 26 Sep 2006, 11:35

Re: ggplot data + abline model

Messagepar Logez Maxime » 15 Mai 2018, 11:29

Bonjour,

la librairie effects te permet de faire cela automatiquement mais avec lattice, sinon une possibilité si ton modèle provient de la fonction lm :

Code : Tout sélectionner

tab <- data.frame(V1 = rnorm(100), V2 = rnorm(100), V3 = rnorm(100))
tab$Reponse <- colSums(t(tab)*c(-1, 2, 3))+rnorm(100, 0, 2)

lm1 <- lm(Reponse ~ V1+V2+V3, data = tab)

tabs <- lapply(c("V1", "V2", "V3"), function(x) {
 nv <- setdiff(c("V1", "V2", "V3"), x)
 mns <- as.list(colMeans(tab[nv]))
 rg <- seq(min(tab[,x]), max(tab[,x]), le = 101)
 mns <- c(mns, list(rg))
 names(mns)[3] <- x
 tab <- do.call(expand.grid, mns)
 tab <- tab[c("V1", "V2", "V3")]
 tab$var <- x
 tab <- cbind(tab[c(x, "var")], predict(lm1, newdata = tab, interval = "confidence"))
 colnames(tab)[1] <- "x"
 tab
})

tab1 <- do.call(rbind, tabs)

ggplot(tab1, aes(x, fit)) + geom_path() +
  geom_ribbon(aes(ymin = lwr, ymax = upr, fill = var), alpha = 0.5) +
  facet_wrap(~var, scales = "free")
Cordialement,
Maxime

Tomas leon
Messages : 22
Enregistré le : 09 Jan 2018, 16:12

Re: ggplot data + abline model

Messagepar Tomas leon » 16 Mai 2018, 07:11

Bonjour à tous,

Merci pour vos réponses !

Malheureusement, je pensais qu'il s'agissait juste d'une difficulté technique, mais finalement il s'agit surtout d'une difficulté mathématique parce qu'après réflexion, ce que je voulais faire est faux ! Je pense que je vais devoir trouver une solution, dans l'idée du graphique que je vous ai demandé, mais il faut que je retravaille tout ça.

Encore merci et dès que j'aurai la solution, je l'a posterai !

Tomas leon
Messages : 22
Enregistré le : 09 Jan 2018, 16:12

Re: ggplot data + abline model

Messagepar Tomas leon » 18 Mai 2018, 16:45

Re à tous !

Ma question se précise dans la même idée de départ :

Voici une partie de mes données. En gros j'ai 6 jeux de données sous des conditions différentes (je voudrais faire 1 graphique en 6 panels dont le premier panel serait celui-ci).

Code : Tout sélectionner



Nb_observation <- as.vector(c( 2,  0,  6,  2,  7,  1,  8,  0,  2,  1,  1,  3, 11,  5,  9,  6,  4,  0,  7,  9))
Nb_observateur <- as.vector(c(31, 35, 35, 35, 39, 39, 39, 39, 39, 41, 41, 42, 43, 43, 45, 45, 47, 48, 51, 51))
inf20 <- as.vector(c(2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 3, 5, 4))
sup20 <- as.vector(c(3, 4, 4, 4, 5, 4, 4, 5, 4, 4, 5, 5, 5, 6, 5, 6, 6, 5, 7, 6))
inf40 <- as.vector(c(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 4, 3))
sup40 <- as.vector(c(4, 5, 5, 5, 6, 5, 5, 6, 5, 5, 6, 6, 6, 7, 6, 7, 7, 7, 9, 7))
inf60 <- as.vector(c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2))
sup60 <- as.vector(c(5, 6, 6,  6,  8,  7,  7,  7,  7,  7,  7,  7,  8,  9,  8,  9,  9,  9, 11,  9))
inf90 <- as.vector(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1))
sup90 <- as.vector(c(10, 11, 11, 11, 15, 13, 13, 14, 12, 13, 13, 13, 14, 17, 15, 17, 17, 16, 21, 18))

data <- cbind.data.frame(Nb_observation, Nb_observateur, inf20, sup20, inf40, sup40, inf60 , sup60, inf90 , sup90)



Voila le graphique que j'ai fait :


Code : Tout sélectionner


plot(data$Nb_observateur, data$Nb_observation, type = "n",  xlab = "Nombre d'observateurs", ylab = "Nombre d'observations", main = "Pour la condition Ia et sous-condition a")

lines(data$Nb_observateur, data$inf20, col = "dark red")
lines(data$Nb_observateur, data$sup20, col = "dark red")

lines(data$Nb_observateur, data$inf40, col = "red")
lines(data$Nb_observateur, data$sup40, col = "red")

lines(data$Nb_observateur, data$inf60, col = "dark orange")
lines(data$Nb_observateur, data$sup60, col = "dark orange")

lines(data$Nb_observateur, data$inf90, col = "yellow")
lines(data$Nb_observateur, data$sup90, col = "yellow")





Il y a deux choses que j'aimerais faire (et donc la je pense que ça pourrait être fait par ggplot mais je n'y arrive pas) :

Dans l'idée du graphique du script que je vous ai envoyé, les "inf" et "sup" sont des bornes des simulations de mon modèle dans l'IC 20% puis 40% puis 60% et enfin 90%. J'aimerais dans un premier temps lisser chacune des courbes ("smooth" ? je ne sais pas s'il existe plusieurs méthodes), et ensuite j'aimerais colorier la surface entre 2 courbes du même IC, par exemple que la surface entre data$inf90 et data$sup90 soit jaune, la surface entre "data$inf60" et "data$60" soit orange etc. Et j'aimerais superposer chacune de ces surfaces coloriées, s'il vous plait.

(ps : il n'y a pas de médiane ou de moyenne dans mon graphique, c'est normal).

Je ferai ensuite le même travail pour chacune des conditions.

Merci pour votre aide !

Tomas leon
Messages : 22
Enregistré le : 09 Jan 2018, 16:12

Re: ggplot data + abline model

Messagepar Tomas leon » 27 Mai 2018, 08:37

Bonjour à tous,

Je fais post sur post, désolé, mais je viens vous apporter la réponse. Ce n'est pas de moi, je ne comprend pas tout, mais ça répond à ma question :

Library :

Code : Tout sélectionner

library(dplyr)
library(tidyr)
library(stringr)
library(forcats)
library(ggplot2)
library(gridExtra)


Transformation des données :

Code : Tout sélectionner

data_long <- data %>%
  as_tibble() %>%
  gather(key = key, value = value, -Nb_obs, -Nb_obst) %>%
  mutate(measure = str_extract(key, "\\D+")) %>%
  mutate(level = str_extract(key, "\\d+")) %>%
  select(-key) %>%
  group_by(level, measure) %>%
  mutate(row = row_number()) %>%
  spread(key = measure, value = value) %>%
  ungroup() %>%
  mutate(level = as.factor(level) %>% fct_rev())

head(data_long)


puis

Code : Tout sélectionner

data_smooth <- data_long %>%
  group_by(level) %>%
  do(Nb_obst = .$Nb_obst,
     inf_smooth = predict(loess(.$inf ~ .$Nb_obst, span = 0.35), .$Nb_obst),
     sup_smooth = predict(loess(.$sup ~ .$Nb_obst, span = 0.35), .$Nb_obst)) %>%
  unnest()

head(data_smooth)


C'est l'argument "span =" qui va venir lisser : "span = 1" lissage important. Je pense qu'il y a moyen de faire cette transformation de façon plus simple et sans utiliser le langage de dplyr, mais pour l'instant comme ça, ça fonctionne...

Et enfin le plot :

Code : Tout sélectionner

ggplot(data_smooth, aes(x = Nb_obst, ymin = inf_smooth, ymax = sup_smooth, fill = level)) +
  geom_ribbon(alpha = 0.6) +
  scale_fill_manual(values = c("20" = "darkred", "40" = "red",
      "60" = "darkorange", "90" = "yellow")) +
  theme_light()



Et pour faire mon multifacet :

Code : Tout sélectionner

grid.arrange(GG_I_1, GG_II_1, GG_I_2, GG_II_2,  GG_I_3, GG_II_3, ncol=2, nrow = 3)



Voila, encore merci!


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité