--- title: "Etude italian wine" author: "Roland Barriot" date: "`r format(Sys.time(), '%d %B, %Y')`" output: html_document: code_folding: show highlight: tango theme: paper toc: no toc_depth: 4 toc_float: yes pdf_document: toc: yes toc_depth: '4' word_document: toc: yes toc_depth: '4' editor_options: chunk_output_type: console always_allow_html: yes --- ```{r} knitr::opts_chunk$set(cache=FALSE) knitr::opts_chunk$set(fig.width=10) # for rstudio #knitr::opts_chunk$set(fig.width=6, fig.height=6) # for rstudio #knitr::opts_chunk$set(fig.width=14, fig.height=14) # for html options(width = 100) ``` # Libs ```{r} library(tidyverse) library(magrittr) # syntaxe, notamment affectation %<>% library(GGally) # plot pairs better than default plot library(plotly) # plots interactifs ``` # read_csv Lecture des données. `read_csv`, `read_tsv`, `read_delim`, ... ```{r} read_csv('wine.data.txt') ``` La 1ère colonne est interpétée comme un nombre (*dbl*) et non un facteur (*fct*) car constituée de 1, 2 ou 3 ; les 3 classes possibles. Lecture en spécifiant les types des colonnes ```{r} tb = read_csv('wine.data.txt', col_types="fddddddddddddd") tb ``` Contenu ```{r} tb %>% summary ``` Renommage des classes en 1: Chianti (C), 2: Montepulciano (M), 3: Valpolicella (V), exemple : ```{r} tb$cultivar as.factor(c('C','M','V')[ tb$cultivar ]) ``` Modification du tibble : fonction `mutate` ```{r} tb %>% mutate(class=as.factor( c('C','M','V'))[ cultivar ] ) ``` Ceci ajoute une dernière colonne "class" à partir de la valeur de *cultivar* de chaque ligne. Pour remplacer la valeur de cultivar par cette classe, on donne le même nom de colonne. ```{r} tb %<>% mutate(cultivar=as.factor( c('C','M','V'))[ cultivar ] ) tb ``` **Remarque :** L'utilisation de `%<>%` de la librairie *magrittr* évite d'avoir à faire `tb = tb %>%` # ggplot2 La lib ggplot2 permet de produire des graphiques de bonnes qualités et repose sur bases saines pour la construction de graphique à partir d'un jeu de données. Consultez par exemple https://www.r-graph-gallery.com/ ![Grammaire des graphiques de ggplot2. source: http://bloggotype.blogspot.com/2016/08/holiday-notes2-grammar-of-graphics.html](http://silico.biotoul.fr/site/images/2/2e/Ggplot-grammar-of-graphics.png) à la tidyverse/ggplot2 (encore pas très facile pour un camembert en 2021 donc on fait un barplot). En *x* les classes et pour chaque classe, les effectifs, sous forme de barplot ```{r} tb %>% ggplot(aes(x=cultivar, fill=cultivar)) + geom_bar(stat = 'count') ``` # Exo sur tidyverse / distribution classe(s)-attribut Considérons la variable *alcohol* et sa distribution par classe : est-ce utile pour déterminer la classe d'un vin ? ```{r} tb %>% ggplot() + geom_boxplot(aes(x=cultivar, y=alcohol)) ``` Il pest possible de rajouter des *geometries* ```{r} tb %>% ggplot(aes(x=cultivar, y=alcohol)) + geom_boxplot() + geom_point() ``` Les points se supperpossent : faire de la transparence et/ou du *jitter* ```{r} tb %>% ggplot(aes(x=cultivar, y=alcohol)) + geom_boxplot() + geom_jitter(width=0.05, alpha=0.2) ``` Plus moderne avec des *violin plots* qui tracent la courbe de densité à la place de la boiîte à moustaches ```{r} tb %>% ggplot(aes(x=cultivar, y=alcohol)) + geom_violin(aes(fill=cultivar)) + geom_jitter(width=0.05, alpha=0.2) + theme_bw() + ggtitle("Distributions des degrés alcoolique par classe de vin") ``` Calcul des moyennes et écart-types par classe → *group_by* et *summarise* ```{r} alcohol = tb %>% group_by(cultivar) %>% summarise(alcohol.mean = mean(alcohol), alcohol.sd = sd(alcohol)) alcohol ``` # pivot_longer (plusieurs colonnes/variable → (variable name, variable value) ) Manip pour avoir des tuples (classe variable value) ```{r} tbg = tb %>% rowid_to_column() %>% pivot_longer(alcohol:proline, names_to='variable', values_to='value') tbg ``` `rowid` sera nécessaire si on veut revenir au format de départ sinon impossible de savoir quelle mesures (d'alcool et de ash) il faut rassembler pour reconstruire le tableau de départ. ```{r} tb %>% pivot_longer(alcohol:proline, names_to='variable', values_to='value') %>% ggplot(aes(cultivar, value, color=cultivar)) + geom_boxplot() + facet_wrap(~ variable) ``` On remarque que *proline* écrase le reste. Plot interactif ```{r} p = tb %>% pivot_longer(alcohol:proline, names_to='variable', values_to='value') %>% ggplot(aes(cultivar, value, color=cultivar)) + geom_boxplot() + facet_wrap(~ variable) ggplotly(p) ``` Il va donc être judicieux de normaliser les données. Nous allons utiliser une normalisation *z-score* qui consiste à centrer-réduire la matrice de données. # group_by → summarise, join, mutate (normalisation) Normalisation (z-score) ```{r} znorm = tbg %>% group_by(variable) %>% summarize(mean=mean(value), sd=sd(value), min = min(value), max=max(value), median=median(value)) znorm ``` jointure et ajout des z-score ```{r} tbg %<>% inner_join(znorm, by='variable') %>% mutate(value.z = (value-mean)/sd) tbg ``` Vérification de la normalisation (moyenne à 0 et écart-type à 1) ```{r} tbg %>% group_by(variable) %>% summarize(m=round(mean(value.z), 4), sd=sd(value.z)) ``` # Formatage de tableau ```{r} znorm %>% knitr::kable() ``` # ggplot + facet Visu ```{r} tbg %>% ggplot(aes(cultivar, value.z, color=cultivar)) + geom_violin() + facet_wrap(~ variable) ``` On y voit mieux. # pivot_wider: (var,val) → columns Pour revenir au format de départ (une colonne par variable) ```{r} tbz = tbg %>% select(rowid, cultivar, variable, value.z) %>% pivot_wider(names_from = variable, values_from=value.z) # tbz = tbg %>% # select(cultivar_id, cultivar, variable, value.z) %>% # spread(key = variable, value=value.z) tbz ``` # geom_point (bivariate analysis) ```{r} tbz %>% ggplot(aes(x=`alcalinity-of-ash`, y=alcohol)) + geom_point() ``` Avec des couleurs et des formes ```{r} tbz %>% ggplot(aes(x=`alcalinity-of-ash`, y=alcohol)) + geom_point(size=3, aes(color=cultivar, shape=cultivar)) ``` http://larmarange.github.io/analyse-R/graphiques-bivaries-ggplot2.html La librairies ggally permet de faire les analyses bivariées sous forme d'un seul plot ```{r cache=T, message=F} tb %>% ggpairs(aes(color=cultivar, alpha=0.1)) ``` La même sur les données normalisées ```{r cache=T, message=F, eval=F} tbz %>% select(-rowid) %>% ggpairs(aes(color=cultivar, alpha=.1)) ``` matrice de corrélations ```{r} tb %>% ggcorr() ``` # ACP Est-ce que des groupes se distinguent à partir des données ? ```{r} tb.acp = tb %>% select(-cultivar) %>% as.matrix %>% princomp(cor=T) tb.acp %>% summary ``` La variance portée par les axes semblent être assez prometteuse. Ajout des coordonnées projettées dans le nouveau repère à 2 dimensions (2 premières composantes principales) ```{r} names(tb.acp$score[,1:2])=c('Comp1','Comp2') tb$Comp1 = tb.acp$score[,1] tb$Comp2 = tb.acp$score[,2] ``` visu ```{r} tb %>% ggplot(aes(Comp1, Comp2, color=cultivar, shape=cultivar)) + geom_point() + ggtitle('ACP normée princomp wine') ``` C'est prometteur (séparation des classes par l'utilisation d'une combinaison des variables).