|
| 1 | +--- |
| 2 | +title: "Devoir n°1" |
| 3 | +author: "Anne Badel" |
| 4 | +date: "`r Sys.Date()`" |
| 5 | +output: |
| 6 | + pdf_document: |
| 7 | + fig_caption: yes |
| 8 | + highlight: pygments |
| 9 | + toc: yes |
| 10 | + toc_depth: 2 |
| 11 | + number_sections: true |
| 12 | + html_document: default |
| 13 | + fontsize: 13pt |
| 14 | +--- |
| 15 | + |
| 16 | +# Quelques paramètres |
| 17 | +```{r settings, include=FALSE, echo=FALSE, eval=TRUE} |
| 18 | +library(knitr) |
| 19 | +
|
| 20 | +options(width = 300) |
| 21 | +# options(encoding = 'UTF-8') |
| 22 | +knitr::opts_chunk$set( |
| 23 | + fig.width = 7, fig.height = 5, |
| 24 | + fig.path = 'figures/TX1_', |
| 25 | + fig.align = "center", |
| 26 | + size = "tiny", |
| 27 | + echo = TRUE, |
| 28 | + eval = TRUE, |
| 29 | + warning = FALSE, |
| 30 | + message = FALSE, |
| 31 | + results = TRUE, |
| 32 | + comment = "") |
| 33 | +
|
| 34 | +options(scipen = 2) |
| 35 | +``` |
| 36 | + |
| 37 | +```{r libraries, include=FALSE, echo=FALSE, eval=TRUE} |
| 38 | +library(knitr) |
| 39 | +library(FactoMineR) |
| 40 | +library(factoextra) |
| 41 | +library(cowplot) |
| 42 | +``` |
| 43 | + |
| 44 | +```{r parametres} |
| 45 | +alpha <- 0.05 |
| 46 | +``` |
| 47 | + |
| 48 | +```{r} |
| 49 | +workdir <- getwd() |
| 50 | +message("Working directory\t", workdir) |
| 51 | +``` |
| 52 | + |
| 53 | +```{r load_expression_table} |
| 54 | +data.folder <- "/Volumes/Data/badel/Documents/Git/DUBII/module-3-Stat-R/seance_2/data" |
| 55 | +
|
| 56 | +meta.file <- "metadata.RDS" # |
| 57 | +abond.file <- "microbiota.abundance.log.RDS" |
| 58 | +meta.path <- file.path(data.folder, meta.file) |
| 59 | +abond.path <- file.path(data.folder, abond.file) |
| 60 | +
|
| 61 | +## Load expression table |
| 62 | +meta.table <- readRDS(meta.path) |
| 63 | +abond.table <- readRDS(abond.path) |
| 64 | +``` |
| 65 | + |
| 66 | +Le `data.frame` `meta.table` contient les données physiologiques des `r nrow(meta.table)` patients, le `data.frame` `abond.table` contient les données de métagénomiques de ces mêmes patients. |
| 67 | + |
| 68 | +# Exercice 1 : comparaison de l'âge moyen des patients malades et sains |
| 69 | + |
| 70 | +## identification de la variable aléatoire étudiée |
| 71 | +La variable étudiée est l'âge des patients `Age` en fonction du facteur `être ou non malade` |
| 72 | + |
| 73 | +### La variable `Age` |
| 74 | +```{r age} |
| 75 | +summary(meta.table$Age) |
| 76 | +par(mfrow=c(1,2)) |
| 77 | +hist(meta.table$Age, main = "histogramme de la variable \"Age\"") |
| 78 | +boxplot(meta.table$Age, main = "boxplot de la variable \"Age\"") |
| 79 | +par(mfrow=c(1,1)) |
| 80 | +``` |
| 81 | +Les individus étudiés ont entre 18 et 78 ans, avec une moyenne de 46,5 ans et une médiane très proche. |
| 82 | +Il n'y a pas de données manquantes |
| 83 | + |
| 84 | +### Le facteur `status` |
| 85 | +```{r ent} |
| 86 | +summary(meta.table$status) |
| 87 | +plot(meta.table$status, main = "histogramme du facteur \"status\"") |
| 88 | +``` |
| 89 | + |
| 90 | +## identification du test à utiliser |
| 91 | +La variable étudiée, l'`Age` est une variable quantitative de paramètre $\mu$ et $\sigma^2$ inconnues. Le facteur `status`est un qualitatif à deux niveaux. Nous allons donc faire un test de comparaison de deux moyennes, dont les hypothèses sont les suivantes : |
| 92 | + |
| 93 | +- $H_0 : \mu_{healthy} = \mu_{liver}$ |
| 94 | +- $H_1 : \mu_{healthy} \neq \mu_{liver}$ |
| 95 | + |
| 96 | +Etant donné que nous sommes dans le cas de comparaison de moyennes dans le cas de grands échantillons (n > 30), nous pouvons faire le test directement, sans nous inquiéter des conditions d'application de ce test. |
| 97 | + |
| 98 | +## `Age` versus `status` |
| 99 | +```{r age-enterotype} |
| 100 | +boxplot(Age ~ status, data = meta.table, main = "\"Age\" versus \"status\"") |
| 101 | +``` |
| 102 | + |
| 103 | +## calcul de la moyenne et de l'écart-type |
| 104 | +Pour calculer moyennes et écart-type dans chacun des groupes, on peut utiliser la fonction `by()` qui renvoit un objet de classe `by`, donc une liste. |
| 105 | +```{r age_by_status} |
| 106 | +mean.by <- by(meta.table$Age, meta.table$status, mean) |
| 107 | +sd.by <- by(meta.table$Age, meta.table$status, sd) |
| 108 | +``` |
| 109 | +ou la fonction `aggregate()` qui renvoit un `dataa.frame` |
| 110 | +```{r age_aggregate_status} |
| 111 | +mean.agg <- aggregate(Age ~ status, data = meta.table, FUN = mean) |
| 112 | +sd.agg <- aggregate(Age ~ status, data = meta.table, FUN = sd) |
| 113 | +``` |
| 114 | + |
| 115 | +Pour afficher les résultats, on peut utiliser la fonction `kable()` |
| 116 | +```{r age_kable_status} |
| 117 | +res <- data.frame(mean.agg[,2], sd.agg[,2]) |
| 118 | +colnames(res) <- c("moyenne", "écart-type") |
| 119 | +rownames(res) <- c("healthy", "liver") |
| 120 | +kable(res) |
| 121 | +``` |
| 122 | + |
| 123 | +## intervalles de confiance |
| 124 | +On sait calculer l'intervalle de confiance d'une moyenne grâce à la formule suivante : |
| 125 | +```{r IC} |
| 126 | +IC = matrix(nrow = 2, ncol = 2) |
| 127 | +rownames(IC) <- c("healthy", "liver") |
| 128 | +colnames(IC) <- c("m.inf", "m.sup") |
| 129 | +``` |
| 130 | +$$IC_{1-\alpha}(\mu) = \Bigg[m - z_{1-{\alpha \over 2}} \sqrt {s^2 \over n} \Bigg]$$ |
| 131 | +soit, pour les individus sains |
| 132 | +```{r IC_mean_healthy} |
| 133 | +nb.ind <- table(meta.table$status) |
| 134 | +m.inf <- res[1,1] - qnorm((1-alpha/2) * sqrt(res[1,2]^2/nb.ind[1])) |
| 135 | +m.sup <- res[1,1] + qnorm((1-alpha/2) * sqrt(res[1,2]^2/nb.ind[1])) |
| 136 | +IC[1,] <- c(m.inf, m.sup) |
| 137 | +``` |
| 138 | +IC($\mu$) = [`r m.inf`, `r m.sup`] |
| 139 | + |
| 140 | +et pour les individus malades |
| 141 | +```{r IC_mean_liver} |
| 142 | +nb.ind <- table(meta.table$status) |
| 143 | +m.inf <- res[2,1] - qnorm((1-alpha/2) * sqrt(res[2,2]^2/nb.ind[2])) |
| 144 | +m.sup <- res[2,1] + qnorm((1-alpha/2) * sqrt(res[2,2]^2/nb.ind[2])) |
| 145 | +IC[2,] <- c(m.inf, m.sup) |
| 146 | +``` |
| 147 | +IC($\mu$) = [`r m.inf`, `r m.sup`] |
| 148 | + |
| 149 | +Les deux intervalles de confiance sont dans le tableau suivant : `r kable(IC)` |
| 150 | + |
| 151 | +## le test statistique |
| 152 | +```{r test} |
| 153 | +(mon.test <- t.test(Age ~ status, data = meta.table, var.equal =T)) |
| 154 | +ma.pvalue <- mon.test$p.value |
| 155 | +``` |
| 156 | + |
| 157 | +Au risque $\alpha$ = `r alpha`, le test est significatif en effet la p.value,`r sprintf("%3.8f", ma.pvalue)`, est inférieure à `r alpha`. On peut donc considérer que l'âge des individus est différent de celui des malades. En moyenne, les individus malades sont plus agés que les individus sains. |
| 158 | + |
| 159 | +# Exercice 2 : ACP sur le jeu de données `microbiota.abudance` |
| 160 | + |
| 161 | +```{r acp} |
| 162 | +ma.pca <- PCA(abond.table, graph = F) |
| 163 | +ma.pca.nonscale <- PCA(abond.table, graph = F, scale.unit = FALSE) |
| 164 | +``` |
| 165 | + |
| 166 | +## part de variabilité |
| 167 | + |
| 168 | +Le premier plan factoriel, les deux premières composantes principales, représente `r ma.pca$eig[2,3]` \% de la variabilité de nos données. Ce n'est pas énorme, et lorsqu'on fait le plot des valeurs propres, |
| 169 | +```{r acp_barplot} |
| 170 | +par(mfrow=c(1,2)) |
| 171 | +barplot(ma.pca.nonscale$eig[,2]) |
| 172 | +barplot(ma.pca$eig[,2]) |
| 173 | +par(mfrow=c(1,1)) |
| 174 | +``` |
| 175 | +on voit qu'on pourrait aller jusqu'à prendre au moins `r sum(ma.pca$eig[, 1]>1)` composantes (valeurs propres > 1). |
| 176 | + |
| 177 | +```{r acp_status_var1} |
| 178 | +par(mfrow=c(1,2)) |
| 179 | +plot(ma.pca.nonscale, choix = "var", label = "none") |
| 180 | +plot(ma.pca, choix = "var", label = "none") |
| 181 | +par(mfrow=c(1,1)) |
| 182 | +``` |
| 183 | + |
| 184 | +Au vu du nombre important de descripteurs (`r ncol(abond.table)`), il est normal qu'on ne distingue pas grand chose. Si ce n'est qu'aucune des variables n'est bien représentée, ni n'a une contribution importante. |
| 185 | + |
| 186 | +On peut essayer de représenter seulement les variables les mieux représentées (cos2 élevés). |
| 187 | +```{r acp_status_var_cos2} |
| 188 | +cos2.p1 <- fviz_pca_var(ma.pca, col.var="cos2", |
| 189 | + gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), |
| 190 | + repel = TRUE, # Avoid text overlapping |
| 191 | + select.var = list(cos2 = 0.4) |
| 192 | + ) |
| 193 | +cos2.cp1 <- fviz_cos2(ma.pca, choice = "var", axes = 1, top = 5) |
| 194 | +cos2.cp2 <- fviz_cos2(ma.pca, choice = "var", axes = 2, top = 5) |
| 195 | +``` |
| 196 | + |
| 197 | +Et les descripteurs ayant la meilleure contribution |
| 198 | +```{r acp_status_contrib} |
| 199 | +contrib.p1 <- fviz_pca_var(ma.pca, col.var="contrib", |
| 200 | + gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), |
| 201 | + repel = TRUE, # Avoid text overlapping |
| 202 | + select.var = list(contrib = 1) |
| 203 | + ) |
| 204 | +plot_grid(cos2.p1, contrib.p1, cos2.cp1, cos2.cp2, ncol = 2, nrow = 1) |
| 205 | +contrib.cp1 <- fviz_contrib(ma.pca, choice = "var", axes = 1, top = 5) |
| 206 | +c.cp1 <- contrib.cp1$data |
| 207 | +c.cp1 <- c.cp1$contrib |
| 208 | +names(c.cp1) <- contrib.cp1$data$name |
| 209 | +c.cp1 <- sort(c.cp1, decreasing = TRUE) |
| 210 | +contrib.cp2 <- fviz_contrib(ma.pca, choice = "var", axes = 2, top = 5) |
| 211 | +c.cp2 <- contrib.cp2$data |
| 212 | +c.cp2 <- c.cp2$contrib |
| 213 | +names(c.cp2) <- contrib.cp1$data$name |
| 214 | +c.cp2 <- sort(c.cp2, decreasing = TRUE) |
| 215 | +plot_grid(contrib.cp1, contrib.cp2, cos2.cp1, cos2.cp2, ncol = 2, nrow = 2) |
| 216 | +``` |
| 217 | + |
| 218 | +Les descripteurs contribuant le plus à la première composante (CP1) sont : `r names(c.cp1[1:5])`. Les individus à droite de l'ACP auront des valeurs plus élevées que la moyenne de `r names(c.cp1[1])`, les individus à gauche de l'ACP auront des plus élevées que la moyenne de `r names(c.cp1[2])`. |
| 219 | +Les descripteurs contribuant le plus à la deuxième composante (CP2) sont : `r names(c.cp2[1])`. Et c'est pas grand chose. |
| 220 | + |
| 221 | + |
| 222 | +## les individus en fonction du statut |
| 223 | +D'après ce que nous avons dit précédemment, les individus sains ont en moyenne des valeurs de `r names(c.cp1[1:5])` plus élevées, alors que les individus malades ont en moyenne des valeurs de `r names(c.cp1[2])` plus élevées. |
| 224 | + |
| 225 | +```{r acp_status_ind} |
| 226 | +plot(ma.pca, choix = "ind", col.ind = meta.table$status) |
| 227 | +legend(-20, 15, legend = c("healthy", "liver"), text.col= 1:2) |
| 228 | +``` |
| 229 | + |
| 230 | + |
| 231 | +## les individus en fonction de l'enterotype |
| 232 | +Attention : il y a des données manquantes |
| 233 | +```{r acp_enterotype1} |
| 234 | +plot(ma.pca, choix = "ind", col.ind = meta.table$Enterotype, cex = 0.5) |
| 235 | +legend(-20, 15, legend = 1:3, text.col= 1:3) |
| 236 | +``` |
| 237 | + |
| 238 | +Il semble que les variables indentifiées précédemment `r names(c.cp1[1:2])` permettent de différencier les individus de type 2 et 3. Les individus de type 1 sont répartis sur l'ensemble du premier plan factoriel. |
| 239 | + |
| 240 | +```{r acp_enterotype2} |
| 241 | +plot(ma.pca, choix = "ind", col.ind = meta.table$Enterotype, cex = 0.5, axes = c(3,4)) |
| 242 | +legend(-20, 15, legend = 1:3, text.col= 1:3) |
| 243 | +``` |
| 244 | +Le plan factoriel (3,4) pour seulement 3% de la variabilité semble distingué les types "1", à gauche des deux autres types. |
| 245 | + |
0 commit comments