|
| 1 | +--- |
| 2 | +title: "Module 10 : Analyse de la variance (ANOVA)" |
| 3 | +subtitle: "Traitement des données I" |
| 4 | +author: "Guyliann Engels & Philippe Grosjean" |
| 5 | +output: |
| 6 | + learnr::tutorial |
| 7 | +tutorial: |
| 8 | + id: "sdd1.10a" |
| 9 | + version: 0.0.1 |
| 10 | +runtime: shiny_prerendered |
| 11 | +--- |
| 12 | + |
| 13 | +```{r setup, include=FALSE} |
| 14 | +library(learnr) |
| 15 | +library(knitr) |
| 16 | +SciViews::R() |
| 17 | +
|
| 18 | +options(tutorial.event_recorder = BioDataScience::record_sdd) |
| 19 | +tutorial_options(exercise.checker = BioDataScience::checker_sdd) |
| 20 | +tutorial_options(exercise.timelimit = 60) |
| 21 | +tutorial_options(exercise.cap = "Code R") |
| 22 | +knitr::opts_chunk$set(echo = FALSE, comment = NA) |
| 23 | +
|
| 24 | +library(BioDataScience) |
| 25 | +``` |
| 26 | + |
| 27 | +```{r, echo=FALSE} |
| 28 | +fixedRow( |
| 29 | + column(9, div( |
| 30 | + img(src = 'images/BioDataScience-128.png', align = "left"), |
| 31 | + h1("Science des données biologiques"), |
| 32 | + "Réalisé par le service d'Écologie numérique des Milieux aquatiques, Université de Mons (Belgique)" |
| 33 | + )), |
| 34 | + column(3, div( |
| 35 | + textInput("user", "Utilisateur :", ""), |
| 36 | + textInput("email", "Email :", "") |
| 37 | + )) |
| 38 | +) |
| 39 | +textOutput("user") # This is newer shown, but required to trigger an event! |
| 40 | +textOutput("email") # Idem! |
| 41 | +``` |
| 42 | + |
| 43 | +```{r, context="server"} |
| 44 | +output$user <- renderText({BioDataScience::user_name(input$user);""}) |
| 45 | +output$email <- renderText({BioDataScience::user_email(input$email);""}) |
| 46 | +updateTextInput(session, "user", value = BioDataScience::user_name()) |
| 47 | +updateTextInput(session, "email", value = BioDataScience::user_email()) |
| 48 | +``` |
| 49 | + |
| 50 | +## Préambule |
| 51 | + |
| 52 | +Si vous n'avez jamais utilisé de tutoriel "learnr", familiarisez-vous d'abord avec son interface [ici](http://biodatascience-course.sciviews.org/sdd-umons/learnr.html). |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | +> Conformément au RGPD ([Règlement Général sur la Protection des Données](https://ec.europa.eu/info/law/law-topic/data-protection/reform/rules-business-and-organisations/principles-gdpr_fr)), nous sommes tenus de vous informer de ce que vos résultats seront collecté afin de suivre votre progression. **Les données seront enregistrées au nom de l'utilisateur apparaissant en haut de cette page. Corrigez si nécessaire !** En utilisant ce tutoriel, vous marquez expressément votre accord pour que ces données puissent être collectées par vos enseignants et utilisées pour vous aider et vous évaluer. Après avoir été anonymisées, ces données pourront également servir à des études globales dans un cadre scientifique et/ou éducatif uniquement. |
| 57 | +
|
| 58 | +## Objectifs |
| 59 | + |
| 60 | +- |
| 61 | + |
| 62 | + |
| 63 | +## La croissance des dents de cochons d'Inde |
| 64 | + |
| 65 | +Vous allez réaliser une analyse complète sur le jeu de données portant sur la croissance des dents de cochons d'Inde. La question est : y a t'il une différence de croissance des dents en fonction de la concentration en supplément administré. |
| 66 | + |
| 67 | +```{r, echo = TRUE} |
| 68 | +toothgrowth <- read("ToothGrowth", package = "datasets", lang = "fr") |
| 69 | +glimpse(toothgrowth) |
| 70 | +``` |
| 71 | + |
| 72 | +Vous pouvez observer que la variable `dose` est encodée en variable numérique et non en variable facteur. Réencodez la variable `dose` afin d'avoir une variable facteur ordonnée. |
| 73 | + |
| 74 | +```{r} |
| 75 | +variable <- c("toothgrowth", "glimpse()", "as.ordered()", "dose", "$") |
| 76 | +sample(variable) |
| 77 | +``` |
| 78 | + |
| 79 | +```{r tg_prepare} |
| 80 | +toothgrowth <- read("ToothGrowth", package = "datasets", lang = "fr") |
| 81 | +``` |
| 82 | + |
| 83 | +```{r toothgrowth1, exercise = TRUE, exercise.setup = "tg_prepare"} |
| 84 | +# réordonner la variable dose |
| 85 | +# |
| 86 | +# visualiser le jeu de données |
| 87 | +# |
| 88 | +``` |
| 89 | + |
| 90 | +```{r toothgrowth1-solution} |
| 91 | +# réordonner la variable dose |
| 92 | +toothgrowth$dose <- as.ordered(toothgrowth$dose) |
| 93 | +# visualiser le jeu de données |
| 94 | +glimpse(toothgrowth) |
| 95 | +``` |
| 96 | + |
| 97 | +```{r toothgrowth1-check} |
| 98 | +#TODO |
| 99 | +``` |
| 100 | + |
| 101 | +Avant de réaliser un test d'hypothèse, vous devez visualiser vos données. Commencez par réaliser un résumé des données. |
| 102 | + |
| 103 | +### Visualisation des données |
| 104 | + |
| 105 | +Vous devez toujours débuter une analyse par visualiser vos données que ce soit sous la forme d'un tableau de données ou encore de graphiques. |
| 106 | + |
| 107 | +Pour réaliser un tableau de données, le snippet est **.hmanova1desc** et renvoit les instructions suivantes : |
| 108 | + |
| 109 | +```{r, echo=FALSE, eval=FALSE} |
| 110 | +DF %>.% |
| 111 | + group_by(., XFACTOR) %>.% |
| 112 | + summarise(., mean = mean(YNUM), sd = sd(YNUM), count = sum(!is.na(YNUM))) |
| 113 | +``` |
| 114 | + |
| 115 | +```{r tg_prepare1} |
| 116 | +toothgrowth <- read("ToothGrowth", package = "datasets", lang = "fr") |
| 117 | +toothgrowth$dose <- as.ordered(toothgrowth$dose) |
| 118 | +``` |
| 119 | + |
| 120 | +```{r toothgrowth2, exercise = TRUE, exercise.setup = "tg_prepare1"} |
| 121 | +
|
| 122 | +``` |
| 123 | + |
| 124 | +```{r toothgrowth2-solution} |
| 125 | +toothgrowth %>.% |
| 126 | + group_by(., dose) %>.% |
| 127 | + summarise(., mean = mean(len), sd = sd(len), count = sum(!is.na(len))) |
| 128 | +``` |
| 129 | + |
| 130 | +```{r toothgrowth2-check} |
| 131 | +#TODO |
| 132 | +``` |
| 133 | + |
| 134 | +Réalisez ensuite une boite de dispersion. Le snippet est **.cbbox** et renvoit les instructions suivantes : |
| 135 | + |
| 136 | +```{r, echo = TRUE, eval = FALSE} |
| 137 | +chart(data = DF, YNUM ~ XFACTOR) + |
| 138 | + geom_boxplot() |
| 139 | +``` |
| 140 | + |
| 141 | +```{r toothgrowth3, exercise = TRUE, exercise.setup = "tg_prepare1"} |
| 142 | +
|
| 143 | +``` |
| 144 | + |
| 145 | +```{r toothgrowth3-solution} |
| 146 | +chart(data = toothgrowth, len ~ dose) + |
| 147 | + geom_boxplot() |
| 148 | +``` |
| 149 | + |
| 150 | +```{r toothgrowth3-check} |
| 151 | +#TODO |
| 152 | +``` |
| 153 | + |
| 154 | +Maintenant que vous avez pris connaissance de vos données, vous pouvez réaliser votre test d'hypothèse en ayant pris connaissance de vos données. |
| 155 | + |
| 156 | +### Anova |
| 157 | + |
| 158 | +#### Vérification des conditions d'applications |
| 159 | + |
| 160 | +Attention, avant de réaliser une analyse de variance vous devez vérifier si la variance de vos différents groupes est homogène au sein de la variable facteur que vous étudiez. |
| 161 | + |
| 162 | +Le test de Bartlett est un outil mis à votre disposition. Le snippet est **.hvbartlett** et renvoit les instructions suivantes : |
| 163 | + |
| 164 | +```{r, echo = TRUE, eval=FALSE} |
| 165 | +bartlett.test(data = DF, YNUM ~ XFACTOR) |
| 166 | +``` |
| 167 | + |
| 168 | +```{r toothgrowth4, exercise = TRUE, exercise.setup = "tg_prepare1"} |
| 169 | +
|
| 170 | +``` |
| 171 | + |
| 172 | +```{r toothgrowth4-solution} |
| 173 | +bartlett.test(data = toothgrowth, len ~ dose) |
| 174 | +``` |
| 175 | + |
| 176 | +```{r toothgrowth4-check} |
| 177 | +#TODO |
| 178 | +``` |
| 179 | + |
| 180 | +```{r quiz1} |
| 181 | +question("Y a t'il homoscédasticité des variances ?", |
| 182 | + answer("oui", correct = TRUE), |
| 183 | + answer("non")) |
| 184 | +``` |
| 185 | + |
| 186 | + |
| 187 | +Vous devez également vérifier sur vos résidus suivent une distribution normale. |
| 188 | + |
| 189 | +- Calculez vos résidus |
| 190 | + |
| 191 | +Le snippet est **.dvresid** et renvoit les instructions suivantes : |
| 192 | + |
| 193 | +```{r, echo = TRUE, eval = FALSE} |
| 194 | +DF %>.% |
| 195 | + mutate(., VAR.res = VAR - ave(VAR, FACTOR)) -> DF2 |
| 196 | +``` |
| 197 | + |
| 198 | +```{r toothgrowth5, exercise = TRUE, exercise.setup = "tg_prepare1"} |
| 199 | +
|
| 200 | +``` |
| 201 | + |
| 202 | +```{r toothgrowth5-solution} |
| 203 | +tootgrowth %>.% |
| 204 | + mutate(., len.res = len - ave(len, dose)) -> toothgrowth |
| 205 | +``` |
| 206 | + |
| 207 | +```{r toothgrowth5-check} |
| 208 | +#TODO |
| 209 | +``` |
| 210 | + |
| 211 | +- Réalisez un graphique quantile-quantile des résidus |
| 212 | + |
| 213 | +Le snippet est **.cuqqnorm** et renvoit les instructions suivantes : |
| 214 | + |
| 215 | +```{r, echo = TRUE, eval=FALSE} |
| 216 | +car::qqPlot(DF[["XNUM"]], distribution = "norm", |
| 217 | + envelope = 0.95, col = "Black", ylab = "XNUM") |
| 218 | +``` |
| 219 | + |
| 220 | +```{r tg_prepare2} |
| 221 | +toothgrowth <- read("ToothGrowth", package = "datasets", lang = "fr") |
| 222 | +toothgrowth$dose <- as.ordered(toothgrowth$dose) |
| 223 | +tootgrowth %>.% |
| 224 | + mutate(., len.res = len - ave(len, dose)) -> toothgrowth |
| 225 | +``` |
| 226 | + |
| 227 | +```{r toothgrowth6, exercise = TRUE, exercise.setup = "tg_prepare2"} |
| 228 | +
|
| 229 | +``` |
| 230 | + |
| 231 | +```{r toothgrowth6-solution} |
| 232 | +car::qqPlot(toothgrowth[["len.res"]], distribution = "norm", |
| 233 | + envelope = 0.95, col = "Black", ylab = "len.res") |
| 234 | +``` |
| 235 | + |
| 236 | +```{r toothgrowth6-check} |
| 237 | +#TODO |
| 238 | +``` |
| 239 | + |
| 240 | +Vos résidus suivent une distribution normale et la variance de vos trois groupes est homogènes. Vous pouvez maintenant réalisez votre ANOVA. |
| 241 | + |
| 242 | +#### ANOVA |
| 243 | + |
| 244 | +Réalisez l'analyse de variances. Le snippet est **.hmanova1** et renvoit les instructions suivantes : |
| 245 | + |
| 246 | +```{r, echo = TRUE, eval=FALSE} |
| 247 | +anova(anova. <- lm(data = DF, YNUM ~ XFACTOR)) |
| 248 | +``` |
| 249 | + |
| 250 | +```{r toothgrowth7, exercise = TRUE, exercise.setup = "tg_prepare1"} |
| 251 | +
|
| 252 | +``` |
| 253 | + |
| 254 | +```{r toothgrowth7-solution} |
| 255 | +anova(anova. <- lm(data = toothgrowth, len ~ dose)) |
| 256 | +``` |
| 257 | + |
| 258 | +```{r toothgrowth7-check} |
| 259 | +#TODO |
| 260 | +``` |
| 261 | + |
| 262 | +Une fois votre ANOVA réalisée, vous avez à votre dispositon un snippet qui vous permet de vérifier la distribution normale de vos résidus. Cette méthode est plus rapide que de calculer vos résidus et d'en faire un graphique quantile-quantile. |
| 263 | + |
| 264 | +```{r, echo = TRUE, eval=FALSE} |
| 265 | +#plot(anova., which = 2) |
| 266 | +anova. %>.% |
| 267 | + chart(broom::augment(.), aes(sample = .std.resid)) + |
| 268 | + geom_qq() + |
| 269 | + #geom_qq_line(colour = "darkgray") + |
| 270 | + labs(x = "Theoretical quantiles", y = "Standardized residuals") + |
| 271 | + ggtitle("Normal Q-Q") |
| 272 | +``` |
| 273 | + |
| 274 | +```{r tg_prepare3} |
| 275 | +toothgrowth <- read("ToothGrowth", package = "datasets", lang = "fr") |
| 276 | +toothgrowth$dose <- as.ordered(toothgrowth$dose) |
| 277 | +anova(anova. <- lm(data = toothgrowth, len ~ dose)) |
| 278 | +``` |
| 279 | + |
| 280 | +Vous observez que vous ne devez changer aucune instruction. Les snippets ont vraiment été conçu afin de vous simplifier vos analyses dans R. |
| 281 | + |
| 282 | +```{r toothgrowth8, exercise = TRUE, exercise.setup = "tg_prepare3"} |
| 283 | +
|
| 284 | +``` |
| 285 | + |
| 286 | +```{r toothgrowth8-solution} |
| 287 | +#plot(anova., which = 2) |
| 288 | +anova. %>.% |
| 289 | + chart(broom::augment(.), aes(sample = .std.resid)) + |
| 290 | + geom_qq() + |
| 291 | + #geom_qq_line(colour = "darkgray") + |
| 292 | + labs(x = "Theoretical quantiles", y = "Standardized residuals") + |
| 293 | + ggtitle("Normal Q-Q") |
| 294 | +``` |
| 295 | + |
| 296 | +```{r toothgrowth8-check} |
| 297 | +#TODO |
| 298 | +``` |
| 299 | + |
| 300 | +Portez une attention toute particulière à la distribution de vos résidus, suivent-ils une distribution normale ? |
| 301 | + |
| 302 | +Votre ANOVA indique qu'il y a au moins une des moyennes qui est significativement différente des autres. Afin de connaitre le niveau dont la moyenne (ou les niveaux) qui est significativement différent des autres moyennes, vous pouvez réaliser une analyses complémentaire de l'ANOVA |
| 303 | + |
| 304 | +```{r, echo = TRUE, eval=FALSE} |
| 305 | +summary(anovaComp. <- confint(multcomp::glht(anova., |
| 306 | + linfct = multcomp::mcp(XFACTOR = "Tukey")))) # Add a second factor if you want |
| 307 | +.oma <- par(oma = c(0, 5.1, 0, 0)); plot(anovaComp.); par(.oma); rm(.oma) |
| 308 | +``` |
| 309 | + |
| 310 | +```{r toothgrowth9, exercise = TRUE, exercise.setup = "tg_prepare3"} |
| 311 | +
|
| 312 | +``` |
| 313 | + |
| 314 | +```{r toothgrowth9-solution} |
| 315 | +summary(anovaComp. <- confint(multcomp::glht(anova., |
| 316 | + linfct = multcomp::mcp(dose = "Tukey")))) # Add a second factor if you want |
| 317 | +.oma <- par(oma = c(0, 5.1, 0, 0)); plot(anovaComp.); par(.oma); rm(.oma) |
| 318 | +``` |
| 319 | + |
| 320 | +```{r toothgrowth9-check} |
| 321 | +#TODO |
| 322 | +``` |
| 323 | + |
| 324 | +```{r quiz2} |
| 325 | +question("Y a t'il un effet significatif de la dose administrée sur la croissance des dents ?", |
| 326 | + answer("oui"), |
| 327 | + answer("non")) |
| 328 | +``` |
| 329 | + |
| 330 | +**Ayez une véritable réfléxion sur l'ensemble de l'analyse que vous venez de réaliser.** Toutes les étapes de cette analyse sont importantes. |
| 331 | + |
| 332 | +## Conclusion |
| 333 | + |
| 334 | +Bravo! Vous venez de terminer votre séance d'exercices dans un tutoriel "learnr". |
| 335 | + |
| 336 | +Laissez nous vos impressions sur cet outil pédagogique ou expérimentez encore dans la zone ci-dessous. Rappelez-vous que pour placer un commentaire dans une zone de code R, vous devez utilisez un dièse (`#`) devant vos phrases. |
| 337 | + |
| 338 | +```{r comm, exercise=TRUE, exercise.lines = 8} |
| 339 | +# Ajout de commentaires |
| 340 | +# ... |
| 341 | +``` |
| 342 | + |
| 343 | +```{r comm-check} |
| 344 | +# Not yet... |
| 345 | +``` |
0 commit comments