PREAMBULES

Plus de 80% de l’analyse des données consiste à bien importer et préparer les données pour faire une analyse statistique.

Un bon plan de collecte et d’analyse est nécessaire. C’est dommage de se donner la peine de collecter des données chèrement acquises en ferme et ensuite de ne pas les utiliser à leur plein potentiel!!!

Le modèle statistique le plus puissant et compliqué ne peut pas pallier à une base de données mal organisée et mal planifiée.

CE TUTORIEL N’EST EN AUCUN CAS UN SUBSTITUT À UN COURS D’ÉPIDEMIOLOGIE OU DE STATISTIQUES, C’EST JUSTE UN OUTIL PRÉSENTÉ DANS LE BUT DE L’UTILISER À DIFFÉRENTES FINS INCLUANT LA DESCRIPTION, VISUALISATION ET L’ANALYSE D’UNE BASE DE DONNÉES (BD).

CE TUTORIEL REQUIERT AUSSI UN MINIMUM DE CONNAISSANCE SUR COMMENT EXECUTER UN CODE SOUS R ET RSTUDIO

Ce travail est un travail en progression, donc n’hésitez pas si il y a des coquilles ou problèmes à me les signaler pour que je les corrige

1. Objectifs de la leçon 1 et préambule

1.1 OBJECTIFS

Le but de l’ensemble du lab d’aujourd’hui est d’être capable : de comprendre comment R fonctionne avec un programme de base d’importer une base de données en format excel ou texte, voir en partant de rien (combinaison de listes).

Dans une seconde étape, nous nous efforcerons de comprendre les notions grammaticales du paquet dplyr de la suite tidyverse qui sont ce que R a de mieux et de plus intuitif dans la manipulation des données vs le codage C++ (ancien codage de R plus oldschool et plus orienté mathématiques).

Je ne suis pas statisticien donc d’emblée je me décharge de toute responsabilité concernant l’usage fait de ce tutoriel. Je l’ai monté pour qu’il soit le plus pratico-pratique et orienté vers la résolution de problèmes de recherche en sciences cliniques vétérinaires et pour les étudiants post-gradués sous ma direction/co-direction.

Pour tout complément d’information sur la gestion des données dans R avec la grammaire du tidyverse, une excellente source de connaissance est le livre du programment Hadley Wickham (R for data science) accessible en ligne.

C’est un livre sacré de tous ceux qui aiment le langage de la suite tidyverse (dont je suis ;-) ). Il utilise des termes simples qui ont pour but de limiter le plus possible les écritures matricielles.

NB: tidy = ranger

1.2 Pourquoi R?

Pour de nombreuses raisons: la première c’est parce que c’est gratuit donc peu importe ce qui arrive à l’avenir, une fois qu’on l’a on n’a pas besoin de payer pour garder la main (pas besoin d’être un universitaire pour l’utiliser).

Donc c’est un investissement en temps qui vaut la peine…

Ensuite c’est un logiciel qui permet par différents paquets/packages d’interagir avec d’autres logiciels (pour les fréquentistes (MLWin, Stata,… ) et les bayésiens (OpenBUGS, Stan…)) sans parler du deep learning, Python et autres…

Enfin, le potentiel des graphiques sur R et sa simplicité par le langage gg (grammar of graphics) dans le paquet ggplot2 sont des avantages indéniables pour communiquer les résultats. Ce qu’on peut faire n’a pas (ou presque) de limites (ex voir les possibilités). En le couplant avec gg_animate ou ggplotly on peut même faire des animations qui sont encore plus spectaculaires lors de présentations!!!

Souvent on utilise des modèles complexes que l’on doit faire comprendre à un public varié (incluant un auditoire non scientifique tel que des producteurs, propriétaires, intervenants variés):

Souvenez-vous: une image vaut 1000 mots! Par un graphique bien choisi, on peut faire passer des messages beaucoup plus efficacement que par du texte et l’explication de modèles statistiques savantes!!!.

Si vous avez R et une connexion internet: vous y arriverez! Dans la majorité des cas qui nous intéressent en médecine vétérinaire pour quelqu’un ayant de l’intérêt en recherche clinique, ce que nous utilisons constitue rarement une nouveauté en terme d’analyse statistique (désolé si vous pensez révolutionner le monde).

Il y a vraisemblablement dans le monde Run paquet, un morceau de code ou chunk que quelqu’un a déjà utilisé et qui peut vous être utile vs partir de rien (un peu comme dans tous les logiciels utilisant des codes)… Cela peut aussi être une personne ou un ancien étudiant du lab qui a fait des analyses similaires (et vous pourrez aussi être cette personne qui communique à un novice (ou à votre équipe de supervision!) son programme utilisé pour sa résidence, MSc ou PhD).

Enfin avec R on ouvre la porte à d’autres interfaces comme RMarkdown qui permet de générer des fichiers html (comme cette leçon du jour qui est toute écrite et codée sur R), pdf, diaporama, livres ou Shiny des applications en ligne…

En résumé: pourquoi j’aime R?

source

Bref, je pourrais en parler des heures durant… Mais le mieux est de vous faire votre propre idée… => ALLONS -Y!!!

1.3 Comment régler les problèmes?

Si vous avez le meilleur logiciel mais que vous êtes le seul à l’utiliser vous aurez des problèmes à un moment donné (c’est inévitable). Ce qui est bien avec R est qu’il est très utilisé. C’est une des raisons les plus importantes de l’utiliser selon moi. Dès que vous avez un bug ou problème, vous googlez votre message d’erreur et vous avez de quoi régler votre solution… Vous pouvez aussi faire appel à un ami ou collègue qui l’utilise.

Pour des problèmes plus complexes, vous avez la communauté RStudio qui permet de suivre spécifiquement certains sujets ou également de soumettre ses problèmes…

1.4 Pré-requis de la leçon de la semaine

Vous devez avoir téléchargé RStudio (en savoir plus sur l’installation voir le lien suivant ).

Vous devez aussi minimalement connaitre la différence entre les fenêtres permettant l’inscription d’un script (source où on code), le panneau de console (portion évaluant le code et l’exécutant), le panneau environnement/historique et le panneau contenant les dossiers/interface package/figures/aide. Ce dernier avec la boite help est parfois utile. C’est également dans ce dernier que vous pouvez spécifiquement regarder les infos sur les paquets ou arguments nécessaires pour une fonction utilisée dans le cadre d’une analyse.

En tout temps vous avez accès à des Cheatsheets résumant les principales informations (sorte d’antisèche qu’il est toujours judicieux d’avoir sous la main…) Ex: pour la base de R

Les autres cheatsheets sont accessibles sur ce site.

Ce sont des indispensables qui résument de façon visuelle toutes les manipulations d’importance.

2. Généralités (bon à savoir pour la suite)

2.1 Au début de chaque session : Téléchargements des paquets/packages

R fonctionne avec des paquets (packages) qui doivent être installés une première fois avec soit via la fenêtre Packages puis Install depuis CRAN (Comprehensive R Archive Network) puis mettre le nom du paquet Mon_beau_package.

Par défaut l’installation des dépendances (ie paquets que le paquet qu’on installe utilise) doit aussi être cochée (elle l’est par défaut).

On peut aussi directement installer un paquet par la console en tapant la commande: install.package(“Mon_beau_package”, dependencies=TRUE)

Cependant, une fois installé dans votre ordi, si vous voulez utiliser ce paquet dans une nouvelle session (ie la prochaine fois que vous regarderez votre programme), il vous faudra indiquer à R que vous voulez utiliser spécifiquement ce paquet. Par convention en général au début de chaque programme ou script on indique les paquets que l’on sollicite dans notre librairie (ce qui sous-entend que vous les avez installés une première fois) par les lignes suivantes:

library(Mon_beau_package)
library(Mon_super_package)
library(Mon_super_genial_package)
etc...

Cela permet aussi aux personnes qui vont inspecter un code par exemple de comprendre pourquoi une fonction ne marche pas si le paquet correspondant n’est pas mentionné… Vous pouvez aussi utiliser l’argument sessionInfo() qui va résumer l’ensemble des caractéristiques de votre session et les versions de paquets utilisés (parfois il se peut qu’il y ait des mises à jours vous empêchant d’utiliser un argument ou autre…)

Attention! R est sensible à la casse (contrairement à SAS) donc la variable Veau est différente de la variable veau, à garder en tête comme cause possible d’un bug sur votre code…

RE-Attention: vous allez forcément avoir des messages d’erreur à un moment donné (c’est comme cela qu’on apprend). La courbe d’apprentissage vaut la peine et à chaque erreur ou oubli qu’on fait, on apprend 10x plus (parole de quelqu’un qui passe par là TRÈS régulièrement…)

Si vous n’utilisez qu’une fonction d’un paquet dans un code vous pouvez aussi directement utiliser cette fonction en la faisant précéder de paquet:: par exemple si j’utilise la fonction de dplyr telle que mutate je peux directement taper dans mon code dplyr::mutate sans avoir chargé le paquet avec library(dplyr). Cependant c’est rare qu’on n’utilise qu’une fois une fonction d’un paquet dans un code donc c’est plus pratique de mettre en début de votre code tous les paquets que vous chargez. Un cas qui peut cependant arriver est lorsque 2 paquets ont le même nom de fonction sans que cela donne le même output. Si vous ne spécifiez pas le paquet alors vous pourrez avoir un message d’erreur

NB: il est également important de regarder lorsque vous allez charger différents paquets que des fonctions de certains paquets ne sont pas en compétition. Je m’explique: il peut arriver que certaines fonctions portent le même noms dans des paquets différents sans qu’elles ne soient liées à la même signification: à ce moment là si vous mettez la fonction sans spécifier le paquet d’ou elle vient vous aurez une erreur car R ne sait pas laquelle vous voulez". Lorsque vous chargez les paquets, dans le code de chargement, R vous mentionne les conflits éventuels (exemple entre la fonction filter de dplyr ou stat pour spécifier ce que l’on veut on devra mettre dplyr::filter). **à garder en tête…*

2.2 Les bonnes pratiques dans R

N’oubliez pas qu’il y a toujours plusieurs façons d’aller vers le même chemin… Cela dépend de nos biais cognitifs et d’un paquet d’autres biais personnels et façons de fonctionner, ce qui peut être parfois problématique lorsqu’on essaie d’expliquer à quelqu’un ce que l’on a fait.

Il est important de bien annoter votre programme dans le script. Vous ne le faites pas nécessairement pour que quelqu’un d’autre ne vous lise mais surtout pour votre futur-vous (vous ne savez pas encore qu’il existe (mais je vous le garantis : il existe)). Votre futur-vous risque de prendre parfois de très haut votre ancien-vous lors d’incompréhension d’une anciennne manipulation…

Le chemin qui vous parait clair aujourd’hui peut vous paraître très difficile et obscur dans 1 ou 2 mois (ou plus) lorsque vous allez vouloir revenir à votre code pour répondre à une question plus spécifique d’un collaborateur, superviseur ou réviseur.

Bien planifier, bien coder, bien annoter

Source

R vous permet d’utiliser les dièses # pour mettre des commentaires (l’équivalent de *et /*commentaire*/ dans SAS)

# ceci est un commentaire qui ne sera pas lu par la console grâce à la dièse mais qui permettra de savoir pourquoi j'ai codé cette commande bizarre à mon logiciel préféré afin de pouvoir m'éclairer lorsque je vais relire cela un soir où je serai moins inspiré...
#ou si je veux passer mon code à un autre personne
#je peux aussi mettre une ancienne commande qui peut être utile ou pas pour ne pas avoir à la recoder ...

Si vous n’avez pas instauré de bonnes pratiques de codage, vous allez perdre beaucoup de temps et être très frustré.

R est largement basé sur les pratiques de reprex pour reproducible examples qui est d’ailleurs un paquet de R. On veut être le plus transparent possible ce qui est une des volontés majeures de la communauté scientifique.

C’est une bonne pratique et cela va dans le sens de la médecine factuelle…

Ce document est donc un ficher html qui est généré grâce à un paquer RMarkdown. Ce paquet a la force de permettre de mettre à la fois du texte et du code R. Vous pouvez cliquer sur la table des matières qui suit durant votre scrolling d’écran…

NB: dans tout ce document: Le code R est dans la portion grisée et peut être directement copié et collé dans votre propre console ou script.

2.3 Chargement de données

On va prendre des exemples concrêts afin de pouvoir être le plus appliqué possible.

Mais d’abord assurez vous de créer un dossier où créer votre script. Le but est de vous assurer que vos commandes et chemins pour accéder aux infos (ou pour stocker une figure) sont bien dans le dossier que vous désirez….

#dans r la commande est la suivante
getwd() # code pour me donner le chemin vers le dossier de sortie de mes outputs par exemple lorsque je voudrais stocker une figure dans un format... (get working directory)
## [1] "C:/Users/p0691070/OneDrive - Universite de Montreal/Site_SBuczinski_fin/content/post"
# code pour spécifier le chemin si nécessaire vers le dossier_voulu (setwd(path.../dossier_voulu) setwd pour set working directory)

Ici on voit que le fichier est dans le dossier Cours_DSC_MSc sur mon bureau dans un dossier Cours_DSC_MSc

Assurez vous d’avoir chargé la suite tidyverse qui contient entre autre les 2 paquets utilisés que nous allons voir plus spécifiquement. Nous chargeons aussi readxl qui lui n’est pas inclus dans la suite tidyverse.

library(tidyverse) # en installantles dépendances de tidyverse vous installez ceux-ci dessous
#library(dplyr)
#library(readr) #ideam pour readr qui lit les données csv, txt
library(readxl) #  readxl qui lit les excel...

En fait si vous downloadez tidyverse (vous avez une suite de paquets déjà inclus dedans). J’ai juste insisté sur les dépendences que nous utisons dans cette portion…

Pour la suite, je donne des exemples basiques. Comme d’habitude le tout est de commencer par un exemple simple puis de le complexifier en fonction des besoins spécifiques. Pour tout complément d’info sur l’importation des données je vous réfère à la Cheatsheet data import. .

2.3.1 Importer un fichier excel

On entre dans le vif du sujet. Pour cette démonstration je me sers de bases de données disponibles en ligne. Notez que vous pouvez aussi mettre votre propre base de données (BD).

J’ai choisi de télécharger une BD disponible dans le livre Veterinary Epidemiology de Ian Dohoo. Ces BD sont accessibles sur le site suivant. Une fois la version xls des fichiers décompressée, je choisis au hasard la BD qui porte le nom calf.xlsx (heu non pas au hasard, car j’aime trop les veaux!!!).

On copie donc ce fichier qu’on peut mettre dans le dossier où se trouve notre document R (ou bien ailleurs, il faudra alors spécifier le chemin d’importation).

Ensuite on va importer le fichier avec la fonctionnalité de read_excel. Je vais nommer cette BD importée veaux (original comme nom!)

veaux <- read_excel("calf.xlsx", sheet="Data") 
#l'argument sheet permet de sélectionner la feuille de données (par défaut il importe la 1ère feuille).

# je dis par défaut car il y a pour chaque fonction de R des arguments par défaut.
# par exemple, par défaut lorsque j'importe une feuille, read_excel passe un argument col.names=TRUE qui signifie que la 1ère ligne est le nom de mes colonnes (comme c'est un défaut, je n'ai pas besoin de le mettre dans ma commande), par contre si je voulais spécifier que la 1ère ligne n'est pas le nom de colonnes je devrais mettre col.names=FALSE)
#voir tout cela en écrivant dans la console ?read_excel

Au fait, j’oubliai, dans R : x <- ou x= veut dire attribue à x la valeur/l’item

Si tout à bien fonctionné vous avez maintenant une BD qui s’appelle veaux qui a été importée.

Maintenant comment la regarder?

Il existe beaucoup de façons différentes de procéder:

2.3.1.1 Ouverture de la BD dans un nouvel onglet

# Façon old school qui permet de voir dans un onglet différent cette fameuse BD
View(veaux)
# Mais ce n'est pas très pratique donc je le déconseille...

autre façon plus simple…

veaux # façon directe...
## # A tibble: 254 x 14
##     case   age breed   sex  attd  dehy   eye  jnts  post pulse  resp  temp   umb
##    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  1670     5     1     1     2  12      NA     0     2    NA    NA  37.6     0
##  2  8124     3     2     0     1  13.5     0     0     0   130   120  39.2     0
##  3  6954     2     3     1     2  NA       1     0     2    NA    NA  NA       1
##  4  2737     3     4     1     1   5       0     0     0   132    40  38.6     0
##  5  5341     3     5     0     1   0       0     0     1   128    48  38.6     1
##  6  6749    10     6     0     1   5.5     0     0     0   160    48  39.6     0
##  7  3234     4     7     0     2   7       0     1     2   180    84  39       1
##  8  2325    14     8     0     1   7       0     0     0   100    20  35       0
##  9  2925     4     9     0     1   5       0     0     0   150    52  39.5     0
## 10  7108     8     1     0     2  10       0     0     2   120    68  37.8     0
## # ... with 244 more rows, and 1 more variable: sepsis <dbl>

Si je veux voir la structure je peux aussi directement utiliser la fonction str

str(veaux)
## tibble [254 x 14] (S3: tbl_df/tbl/data.frame)
##  $ case  : num [1:254] 1670 8124 6954 2737 5341 ...
##  $ age   : num [1:254] 5 3 2 3 3 10 4 14 4 8 ...
##  $ breed : num [1:254] 1 2 3 4 5 6 7 8 9 1 ...
##  $ sex   : num [1:254] 1 0 1 1 0 0 0 0 0 0 ...
##  $ attd  : num [1:254] 2 1 2 1 1 1 2 1 1 2 ...
##  $ dehy  : num [1:254] 12 13.5 NA 5 0 5.5 7 7 5 10 ...
##  $ eye   : num [1:254] NA 0 1 0 0 0 0 0 0 0 ...
##  $ jnts  : num [1:254] 0 0 0 0 0 0 1 0 0 0 ...
##  $ post  : num [1:254] 2 0 2 0 1 0 2 0 0 2 ...
##  $ pulse : num [1:254] NA 130 NA 132 128 160 180 100 150 120 ...
##  $ resp  : num [1:254] NA 120 NA 40 48 48 84 20 52 68 ...
##  $ temp  : num [1:254] 37.6 39.2 NA 38.6 38.6 39.6 39 35 39.5 37.8 ...
##  $ umb   : num [1:254] 0 0 1 0 1 0 1 0 0 0 ...
##  $ sepsis: num [1:254] 0 0 1 0 1 0 1 0 0 0 ...

Un autre chemin que j’aime beaucoup est le print(dfSummary)du paquet summarytools

library(summarytools) #permet d'avoir des outputs plus "friendly users" n'oubliez pas de le charger une premiere fois avec install.package()
print(dfSummary(veaux, valid.col = FALSE, graph.magnif = 0.75), 
      max.tbl.height = 300, method = "render")

Data Frame Summary

veaux

Dimensions: 254 x 14
Duplicates: 0
No Variable Stats / Values Freqs (% of Valid) Graph Missing
1 case [numeric] Mean (sd) : 5006.2 (2799.3) min < med < max: 1294 < 4908.5 < 10354 IQR (CV) : 4607.2 (0.6) 254 distinct values 0 (0%)
2 age [numeric] Mean (sd) : 9.4 (6.2) min < med < max: 1 < 8 < 28 IQR (CV) : 8 (0.7) 27 distinct values 1 (0.39%)
3 breed [numeric] Mean (sd) : 5 (2.8) min < med < max: 1 < 6 < 9 IQR (CV) : 6 (0.6)
1:29(11.4%)
2:56(22.1%)
3:20(7.9%)
4:11(4.3%)
5:3(1.2%)
6:25(9.8%)
7:20(7.9%)
8:84(33.1%)
9:6(2.4%)
0 (0%)
4 sex [numeric] Min : 0 Mean : 0.5 Max : 1
0:121(48.0%)
1:131(52.0%)
2 (0.79%)
5 attd [numeric] Mean (sd) : 1.1 (0.5) min < med < max: 0 < 1 < 2 IQR (CV) : 0 (0.5)
0:28(11.3%)
1:174(70.2%)
2:46(18.6%)
6 (2.36%)
6 dehy [numeric] Mean (sd) : 7 (3.7) min < med < max: 0 < 7.5 < 15 IQR (CV) : 5 (0.5) 18 distinct values 14 (5.51%)
7 eye [numeric] Min : 0 Mean : 0 Max : 1
0:226(95.8%)
1:10(4.2%)
18 (7.09%)
8 jnts [numeric] Mean (sd) : 0.1 (0.5) min < med < max: 0 < 0 < 4 IQR (CV) : 0 (3.2)
0:216(88.9%)
1:21(8.6%)
2:5(2.1%)
4:1(0.4%)
11 (4.33%)
9 post [numeric] Mean (sd) : 0.9 (0.8) min < med < max: 0 < 1 < 2 IQR (CV) : 2 (0.9)
0:93(37.5%)
1:86(34.7%)
2:69(27.8%)
6 (2.36%)
10 pulse [numeric] Mean (sd) : 115.9 (29.5) min < med < max: 30 < 120 < 200 IQR (CV) : 32 (0.3) 48 distinct values 9 (3.54%)
11 resp [numeric] Mean (sd) : 38.8 (19.7) min < med < max: 12 < 32 < 120 IQR (CV) : 24 (0.5) 43 distinct values 19 (7.48%)
12 temp [numeric] Mean (sd) : 38.1 (1.7) min < med < max: 32 < 38.6 < 42 IQR (CV) : 2.7 (0) 63 distinct values 7 (2.76%)
13 umb [numeric] Min : 0 Mean : 0.2 Max : 1
0:188(77.4%)
1:55(22.6%)
11 (4.33%)
14 sepsis [numeric] Min : 0 Mean : 0.3 Max : 1
0:181(71.3%)
1:73(28.7%)
0 (0%)

Generated by summarytools 0.9.6 (R version 4.0.2)
2020-07-08

2.3.1.2 Résumé de la BD

#ici je demande juste les caractéristiques de cette BD
summary(veaux)
##       case            age             breed            sex        
##  Min.   : 1294   Min.   : 1.000   Min.   :1.000   Min.   :0.0000  
##  1st Qu.: 2598   1st Qu.: 5.000   1st Qu.:2.000   1st Qu.:0.0000  
##  Median : 4908   Median : 8.000   Median :6.000   Median :1.0000  
##  Mean   : 5006   Mean   : 9.364   Mean   :5.024   Mean   :0.5198  
##  3rd Qu.: 7206   3rd Qu.:13.000   3rd Qu.:8.000   3rd Qu.:1.0000  
##  Max.   :10354   Max.   :28.000   Max.   :9.000   Max.   :1.0000  
##                  NA's   :1                        NA's   :2       
##       attd            dehy             eye               jnts      
##  Min.   :0.000   Min.   : 0.000   Min.   :0.00000   Min.   :0.000  
##  1st Qu.:1.000   1st Qu.: 5.000   1st Qu.:0.00000   1st Qu.:0.000  
##  Median :1.000   Median : 7.500   Median :0.00000   Median :0.000  
##  Mean   :1.073   Mean   : 7.033   Mean   :0.04237   Mean   :0.144  
##  3rd Qu.:1.000   3rd Qu.:10.000   3rd Qu.:0.00000   3rd Qu.:0.000  
##  Max.   :2.000   Max.   :15.000   Max.   :1.00000   Max.   :4.000  
##  NA's   :6       NA's   :14       NA's   :18        NA's   :11     
##       post            pulse            resp             temp      
##  Min.   :0.0000   Min.   : 30.0   Min.   : 12.00   Min.   :32.00  
##  1st Qu.:0.0000   1st Qu.:100.0   1st Qu.: 24.00   1st Qu.:36.60  
##  Median :1.0000   Median :120.0   Median : 32.00   Median :38.60  
##  Mean   :0.9032   Mean   :115.9   Mean   : 38.79   Mean   :38.06  
##  3rd Qu.:2.0000   3rd Qu.:132.0   3rd Qu.: 48.00   3rd Qu.:39.30  
##  Max.   :2.0000   Max.   :200.0   Max.   :120.00   Max.   :42.00  
##  NA's   :6        NA's   :9       NA's   :19       NA's   :7      
##       umb             sepsis      
##  Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.0000  
##  Mean   :0.2263   Mean   :0.2874  
##  3rd Qu.:0.0000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :1.0000  
##  NA's   :11
# par défaut r me donne pour chaque variable des indicateurs de distribution

Notez bien que R va arbitrairement attribuer le format de chaque variable selon ce qui lui parait le plus adéquat durant l’importation. Par exemple dans ce cas nous voyons que l’identifiant (numéro de boucle) des veaux est indiqué comme une variable numérique et évalué comme tel. On y reviendra par la suite.

De même, pour certaines variables catégoriques codées en chiffre (ex la race breed), ces données ne veulent rien dire…

Enfin ce qui est intéressant est que R vous mentionne pour toutes les variables, le nombre de données manquantes. Dans R par convention les données manquantes sont codées par NA. Dans notre fichier importé original les données manquantes ont été remplacées par NA.

NB: Ici je vous indique un défi spécifique de R qui est que ce logiciel va tout le temps vous ramener vos données manquantes dans le visage (contrairement à la plupart des logiciels qui passent cette info sous silence…

Enfin pour savoir la dimension de votre BD (nombre de lignes et de colonnes) une commande plus simple existe.

dim(veaux)
## [1] 254  14

J’ai donc 254 lignes et 14 colnnes dans ma BD veaux.

Notez tout de suite r donne les lignes et les colonnes dans cet ordre (voir partie 3)…

application lorsque vous cherchez une cellule dans une matrice [a,b] a est la ligne et b la colonne

2.3.1.3 Visualiser rapidement le schéma d’importation

library(visdat)
vis_dat(veaux)

Je peux rapidement voir comment R a classifié les variables de ma BD avec la fonction vis_dat du paquet visdat. Ici comme mentionné précédemment tout est numérique.

2.3.1.4 Nombre restreint de lignes ou colonnes de la BD

head(veaux, n=8)
## # A tibble: 8 x 14
##    case   age breed   sex  attd  dehy   eye  jnts  post pulse  resp  temp   umb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  1670     5     1     1     2  12      NA     0     2    NA    NA  37.6     0
## 2  8124     3     2     0     1  13.5     0     0     0   130   120  39.2     0
## 3  6954     2     3     1     2  NA       1     0     2    NA    NA  NA       1
## 4  2737     3     4     1     1   5       0     0     0   132    40  38.6     0
## 5  5341     3     5     0     1   0       0     0     1   128    48  38.6     1
## 6  6749    10     6     0     1   5.5     0     0     0   160    48  39.6     0
## 7  3234     4     7     0     2   7       0     1     2   180    84  39       1
## 8  2325    14     8     0     1   7       0     0     0   100    20  35       0
## # ... with 1 more variable: sepsis <dbl>
tail(veaux, n=5)
## # A tibble: 5 x 14
##    case   age breed   sex  attd  dehy   eye  jnts  post pulse  resp  temp   umb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  4870     1     9     0     1     0     0     0     0   112    48  39.3     1
## 2  9805     3     9     0     1     5     0     0     1   132    28  39       0
## 3  4869     2     9     0     0     5     0     0     0   140    30  39.3     0
## 4  2926     3     9     0     0     5     0     0     0   200    70  39.8     0
## 5  4186    25     9     0     0     0    NA    NA     0   160    NA  39.7    NA
## # ... with 1 more variable: sepsis <dbl>
# je demande à voir les 8 premières lignes
# notez que vous pourriez demander les dernières lignes avec la fonction tail(veaux, n=)

Cela permet de voir si votre processus d’importation a du sens mais aussi le défaut de codage de chacune des variables (à savoir comment R les a classé par défaut… pour que vous prévoyiez de suite des changements éventuels…).

Ici on voit que la classe des variables est la classe dbl (double) qui est le défaut des variables quantitatives dans R. On verra plus tard pour la spécification des variables.

2.3.1.5 Apparté sur les variables dans R (vous pouvez passer ce point, c’est juste pour ceux qui veulent comprendre les subtilités dans la façon de traiter les données)

Dans R les variables ont toutes un des formats suivants:

Bien planifier, bien coder, bien annoter

Source H.Wickham

À la base 3 formats de base des données dans R (on parle de vecteurs atomiques)

Vecteurs atomiques

  • Donnée Logical TRUE vs FALSE ou aussi en abrégé T/F
  • Donnée Numeric qui est soit un chiffre réel (double ex: 2.7693 ou 2.1 ou 4) ou un entier integer qui sera alors entré avec un L après le nombre ex: (c(3L, 4L, 8L…))
  • Donnée character qui est une donnée entrée entre des guillemets ex : “blabla” ou des apostrophes ‘blabla’ => ici on va trouver toutes les variables telles que des variables catégoriques.

Lorsqu’on a un ensemble de vecteurs atomiques de même format on parle de vecteur (c(“bleu”, “blanc”, “rouge”) ou c(1.4, 3, 7).

Si on a un ensemble avec plusieurs formats on parle de liste ex: c(1, 3.5, F, “bleu”)

En plus s’ajoute l’élément NULL…

2.3.2 Chargement d’une BD sous le format txt ou csv

Je ne perdrai pas trop de temps ici mais cela suit un schéma similaire. J’ai été chercher une BD sur le net qui parle d’IRM… je l’appellerai IRM (très original).

Le lien pour la charger est http://courses.washington.edu/b517/Datasets/MRI.txt

On peut aller la chercher directement par ce chemin. J’utilise alors read_csv2qui vient du package readr(j’ai déjà utilisé cela pour une grosse base de données txt)

IRM <- read_csv2("http://courses.washington.edu/b517/Datasets/MRI.txt", 
                 col_names = TRUE)
#Notez la similitude avec le readexcel

J’ai une bd avec 735 lignes et 1 colonne.

On a donc un problème. Voyons y de plus près…

head(IRM, n=10) # je regarde les 10 premières lignes
## # A tibble: 10 x 1
##    `ptid mridate age male race weight height  packyrs yrsquit   alcoh physact c~
##    <chr>                                                                        
##  1 1  120791  72    1    2  173.0  169.0  54.0000       0  0.0000  9.8400   0  ~
##  2 2   90192  81    0    2  139.0  170.0   0.0000       0  0.2500  0.7800   0  ~
##  3 3   82092  90    1    2  145.0  170.0   0.0000       0  1.2500  1.6350   0  ~
##  4 4   73192  72    1    1  190.0  181.0  33.0000      17  9.5000  3.5175   0  ~
##  5 5  111691  70    0    1  153.0  158.5   0.0000       0  0.2500  0.7500   0  ~
##  6 6   82292  72    1    4  154.5  171.0  58.5000      21 21.0000  3.0300   0  ~
##  7 7   71892  75    1    1  161.5  175.0  30.0000      12  0.0000  1.1800   0  ~
##  8 8   82692  75    1    2  158.2  170.5   0.0000       0  1.0000  6.0525   0  ~
##  9 9   80692  67    0    1  168.0  158.5   0.0000       0  0.0000  0.9000   0  ~
## 10 10  122191  70    0    1  127.0  167.5  16.4500       0  8.0000  0.1350   0 ~

Que voit-on? mon importation n’a pas spécifié de séparation entre les données.. tapez dans la console ?read_csv2(vous appelez la fonction d’aide et vous verrez alors mon erreur)

On recommence donc le processus en y ajoutant une petite modification suite à cette lecture édifiante…

IRM <-  read.table("http://courses.washington.edu/b517/Datasets/MRI.txt", sep = "" , header =T )

J’ai une bd avec 735 lignes et 30 colonnes. OUF!!!

Ici il faut dire 2 choses: J’ai fait l’erreur de me fier sur une ancienne importation d’un fichier txt où les données étaient séparées par un “;” donc dans ce cas là on utilise bien read_csv2le read_csvs’utilise pour les fichiers séparés par une “,”. enfin readrme permet aussi de lire des fichiers texte séparés par une tabulation par read_tsvpour read tab separated values. Or en regardant ma BD j’ai vu que la séparation avait été faite par des espaces en quantité variables entre chaque variables…

Bref pour m’en sortir j’ai utilisé l’argument r de base qui est read.table. En utilisant cet argument je spécifie le type de séparateur par l’argument sep="". Notez que j’ai aussi mentionné que la 1ère ligne contient les noms des variables…header=T.

*Pour l’instant je n’insiste pas sur les différences entre les fonctions read_?et read.?les _ sont généralement l’apanage des paquets de la suite tidyverse . On y reviendra éventuellement…

head(IRM, n=4) # je demande les 4 premières lignes
##   ptid mridate age male race weight height packyrs yrsquit alcoh physact chf
## 1    1  120791  72    1    2    173    169      54       0  0.00  9.8400   0
## 2    2   90192  81    0    2    139    170       0       0  0.25  0.7800   0
## 3    3   82092  90    1    2    145    170       0       0  1.25  1.6350   0
## 4    4   73192  72    1    1    190    181      33      17  9.50  3.5175   0
##   chd stroke diabet genhlth ldl alb crt plt sbp    aai   fev dsst atrophy whgrd
## 1   1      2      0       3 135 3.7 1.4 275 139 1.0303 1.284   25      20     2
## 2   0      0      0       2  84 3.8 1.3 142 146 1.1104 2.553   51      43     2
## 3   0      0      0       3 115 4.2 1.2 192 134 1.0136 2.383   27      35     1
## 4   0      0      0       2  61 4.3 1.1 133 147 0.9800 2.699   43      32     2
##   numinf volinf obstime death
## 1      1 7.4613    2110     0
## 2      3 0.1414    1841     0
## 3      2 0.1885    1853     0
## 4      1 0.0419    1873     0
summary(IRM)
##       ptid          mridate            age             male      
##  Min.   :  1.0   Min.   : 10192   Min.   :65.00   Min.   :0.000  
##  1st Qu.:184.5   1st Qu.: 66642   1st Qu.:71.00   1st Qu.:0.000  
##  Median :368.0   Median : 80992   Median :74.00   Median :0.000  
##  Mean   :368.0   Mean   : 76423   Mean   :74.57   Mean   :0.498  
##  3rd Qu.:551.5   3rd Qu.: 91392   3rd Qu.:78.00   3rd Qu.:1.000  
##  Max.   :735.0   Max.   :123191   Max.   :99.00   Max.   :1.000  
##                                                                  
##       race           weight          height         packyrs      
##  Min.   :1.000   Min.   : 74.0   Min.   :139.0   Min.   :  0.00  
##  1st Qu.:1.000   1st Qu.:138.5   1st Qu.:158.0   1st Qu.:  0.00  
##  Median :1.000   Median :158.0   Median :165.9   Median :  6.50  
##  Mean   :1.318   Mean   :159.9   Mean   :165.8   Mean   : 19.60  
##  3rd Qu.:1.000   3rd Qu.:179.0   3rd Qu.:173.2   3rd Qu.: 33.75  
##  Max.   :4.000   Max.   :264.0   Max.   :190.5   Max.   :240.00  
##                                                  NA's   :1       
##     yrsquit           alcoh            physact             chf         
##  Min.   : 0.000   Min.   : 0.0000   Min.   : 0.0000   Min.   :0.00000  
##  1st Qu.: 0.000   1st Qu.: 0.0000   1st Qu.: 0.5537   1st Qu.:0.00000  
##  Median : 0.000   Median : 0.0192   Median : 1.3125   Median :0.00000  
##  Mean   : 9.661   Mean   : 2.1094   Mean   : 1.9223   Mean   :0.05578  
##  3rd Qu.:18.500   3rd Qu.: 1.1442   3rd Qu.: 2.5125   3rd Qu.:0.00000  
##  Max.   :56.000   Max.   :35.0000   Max.   :13.8150   Max.   :1.00000  
##                                                                        
##       chd             stroke           diabet          genhlth     
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :1.000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:2.000  
##  Median :0.0000   Median :0.0000   Median :0.0000   Median :3.000  
##  Mean   :0.3347   Mean   :0.2367   Mean   :0.1075   Mean   :2.588  
##  3rd Qu.:0.0000   3rd Qu.:0.0000   3rd Qu.:0.0000   3rd Qu.:3.000  
##  Max.   :2.0000   Max.   :2.0000   Max.   :1.0000   Max.   :5.000  
##                                                                    
##       ldl             alb             crt             plt       
##  Min.   : 11.0   Min.   :3.200   Min.   :0.500   Min.   : 92.0  
##  1st Qu.:102.0   1st Qu.:3.800   1st Qu.:0.900   1st Qu.:201.8  
##  Median :125.0   Median :4.000   Median :1.000   Median :239.0  
##  Mean   :125.8   Mean   :3.994   Mean   :1.064   Mean   :246.0  
##  3rd Qu.:147.0   3rd Qu.:4.200   3rd Qu.:1.200   3rd Qu.:285.0  
##  Max.   :247.0   Max.   :5.000   Max.   :4.000   Max.   :539.0  
##  NA's   :10      NA's   :2       NA's   :2       NA's   :7      
##       sbp             aai              fev              dsst      
##  Min.   : 78.0   Min.   :0.3171   Min.   :0.4083   Min.   : 0.00  
##  1st Qu.:118.0   1st Qu.:1.0269   1st Qu.:1.7450   1st Qu.:32.00  
##  Median :130.0   Median :1.1121   Median :2.1580   Median :40.00  
##  Mean   :131.1   Mean   :1.1032   Mean   :2.2068   Mean   :41.06  
##  3rd Qu.:142.0   3rd Qu.:1.2070   3rd Qu.:2.6490   3rd Qu.:50.00  
##  Max.   :210.0   Max.   :1.7284   Max.   :4.4710   Max.   :82.00  
##                  NA's   :9        NA's   :10       NA's   :12     
##     atrophy          whgrd           numinf           volinf        
##  Min.   : 5.00   Min.   :0.000   Min.   :0.0000   Min.   :  0.0000  
##  1st Qu.:27.00   1st Qu.:1.000   1st Qu.:0.0000   1st Qu.:  0.0000  
##  Median :35.00   Median :2.000   Median :0.0000   Median :  0.0000  
##  Mean   :35.98   Mean   :2.007   Mean   :0.6109   Mean   :  3.2230  
##  3rd Qu.:44.00   3rd Qu.:3.000   3rd Qu.:1.0000   3rd Qu.:  0.0942  
##  Max.   :84.00   Max.   :9.000   Max.   :5.0000   Max.   :196.9778  
##                  NA's   :1                        NA's   :1         
##     obstime         death      
##  Min.   :  68   Min.   :0.000  
##  1st Qu.:1837   1st Qu.:0.000  
##  Median :1879   Median :0.000  
##  Mean   :1804   Mean   :0.181  
##  3rd Qu.:2044   3rd Qu.:0.000  
##  Max.   :2159   Max.   :1.000  
## 
vis_dat(IRM)

Ici je vois bien comment les variables sont classées dans R par défaut suite à mon importation.

BON VOUS COMPRENEZ LE PRINCIPE

EN RÉSUMÉ : IMPORTATION ET ENSUITE VISUALISATION RAPIDE DE LA BASE DE DONNÉES…

BRAVO VOUS AVEZ RÉUSSI L’ÉTAPE 1 : IMPORTATION D’UNE BD

Pour plus d’infos chapitre 11 du livre de Wickham et Grolemund (R For data science) et readr cheatsheet

Prochaine étape: on travaille avec nos données pour explorer notre BD

2.4 Finalement: Chargement et entrée manuelle

Dans certains cas, vous n’avez pas de dossier excel ou spécifique mais quelques données que vous voulez entrer de façon directe dans votre logiciel préféré…

Imaginons que je veuille entrer 3 colonnes représentant des variables spécifiques. R fonctionne comme différents logiciels sous la forme d’écriture vectorielle et matricielle. Pour faire simple:

1- vous rentrez le contenu des colonnes sous la forme d’une concaténation

2- vous faites cela pour les différentes variables

3- vous fusionnez le tout sous la forme d’une table que vous pouvez analyser

Exemple concrêt…

Je veux colliger une table avec des groupes de signes cliniques de différents types (variable group qui a 3 catégories sous forme de texte…). Ensuite une variables signes spécifiques (variable clin). Enfin je collige le nombre de cas pour ces 3 variables (variable valuenumérique).

Finalement, j’aimerai créer la jonction de ces 3 colonnes pour former une base de donnnées essai. Les étapes sont développées ci-dessous et passent par la notion de concaténation / combinaison.. c(terme1, terme2, ...)

clin <- c("Depression", "Anorexia", "Pyrexia", "Milk drop", "Weight loss", "Recumb.",
         "Nasal discharge", "Cough","Increased respiratory rate", "Dyspnea", "Open mouth breathing", "Ocular discharge",
         "Diarrhea", "Salivation", "Emphysema") 
# j'associe à clin la liste de termes suivants regroupés après c() et séparés de virgules. comme ce sont des caractères et pas des nombres je dois entourer chque nom de " "

# je crée ensuite ma colonne group qui est une concaténation ou une combinaison de 3 termes qui sont répétés 6 fois pour General signs et respiratory sings et 3 fois pour Other signs. J'utilise la fonction rep(x, n) où n est le nombre de répétition...

group <- c(rep("General signs", 6), rep("Respiratory signs", 6), rep("Other signs", 3))
#ici j'aurai pu aussi me passer de rep et écrir 6 fois de suite "General signs" ifem pour Resp et 3 fois pour Other signs... c'est plus long

value <- c(6,8,19,4,1,1,18,17,10,16,2,8,3,1,2) #ici c'est une liste dans l'ordre de ma BD de nombre... donc pas de " " 
essai <- data.frame(group, clin, value) #je regroupe mes listes de taille identique en format "data.frame

#je regroupe les 3 vecteurs créés en une data.frame qui s'appelle essai

head(essai, 7) # ensuite je regarde si ça a marché...
##               group            clin value
## 1     General signs      Depression     6
## 2     General signs        Anorexia     8
## 3     General signs         Pyrexia    19
## 4     General signs       Milk drop     4
## 5     General signs     Weight loss     1
## 6     General signs         Recumb.     1
## 7 Respiratory signs Nasal discharge    18

C’est fait! Notez ici que R a détecté que groupet clin sont des facteurs fctr qui sont dans R l’équivalent de variables de classe dans SAS (ie catégorique… on y reviendra au chapitre 4). valueest une variable numérique…

vis_dat(essai)

3. Manipulation d’une base de données dans R

Nous avons la BD veaux qui va nous servir d’exemple par la suite… Maintenant il nous faut sortir des informations pertinentes la concernant. Comme R fonctionne sous la forme d’un outil mathématique, il stocke les BD sous la forme de matrice (nombre de lignes*nombre de colonnes). On peut par exemple demander à revoir une cellule particulière.

Pour ce faire on va préciser la ligne et la colonne sous la forme d’une commande mentionnant la BD accompagnée des termes [].

#par exemple pour demander la cellule de la 4ème ligne et la 3ème colonne

veaux[4,3]
## # A tibble: 1 x 1
##   breed
##   <dbl>
## 1     4
#pour demander la ligne complète
veaux[4,]
## # A tibble: 1 x 14
##    case   age breed   sex  attd  dehy   eye  jnts  post pulse  resp  temp   umb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  2737     3     4     1     1     5     0     0     0   132    40  38.6     0
## # ... with 1 more variable: sepsis <dbl>
#pour demander une colonne complète (colonne 3)
veaux[,3]
## # A tibble: 254 x 1
##    breed
##    <dbl>
##  1     1
##  2     2
##  3     3
##  4     4
##  5     5
##  6     6
##  7     7
##  8     8
##  9     9
## 10     1
## # ... with 244 more rows
# je peux aussi demander plusieurs lignes ou colonnes (ici 3ème ligne, colonnes 2 à 5)
veaux[3,2:5]
## # A tibble: 1 x 4
##     age breed   sex  attd
##   <dbl> <dbl> <dbl> <dbl>
## 1     2     3     1     2
#vous comprenez le principe...

C’est du calcul de matrice avec la notation [ligne,colonne] et on peut ainsi faire différentes choses avec cela. On utilise le terme : ex: x:y qui équivaut à de x à y…

Je n’irai pas plus loin sur toutes les notions spécifiques que l’on peut développer (il y en a une pléthore…). Je vous réfère aux notions de listes, vecteurs, matrices ou data.frame et arrays

4. Transformer ses données

Comme on l’a vu, on peut importer des données. Maintenant il faut les organiser. Si nous revenons dans notre base de données veaux nous allons nous attarder sur sa structure.

Je vous réfère plus spécifiquement au livre de Garrett Grolemund sur les bases de R (il est beaucoup plus complet que ce petit tutoriel)

head(veaux, 5) # 5 lignes de veaux...
## # A tibble: 5 x 14
##    case   age breed   sex  attd  dehy   eye  jnts  post pulse  resp  temp   umb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  1670     5     1     1     2  12      NA     0     2    NA    NA  37.6     0
## 2  8124     3     2     0     1  13.5     0     0     0   130   120  39.2     0
## 3  6954     2     3     1     2  NA       1     0     2    NA    NA  NA       1
## 4  2737     3     4     1     1   5       0     0     0   132    40  38.6     0
## 5  5341     3     5     0     1   0       0     0     1   128    48  38.6     1
## # ... with 1 more variable: sepsis <dbl>

On voit ici qu’on a différentes variables codées toutes en nombre (dblou double, r reconnait aussi comme format numérique les formats dichotomique 0/1). Si on veut savoir le format d’une données ou d’un vecteur (liste de données) on peut demander à r le code is() (dans la parenthèse on trouve le vecteur ou la variable). Plusieurs autres commandes me permettent d’arriver au résultat telles que class().

is(veaux$age)
## [1] "numeric" "vector"

Ici j’ai introduit un nouveau concept de base dans r le symbole $. Ce symbole doit accompagner la variable que vous cherchez avec la BD sous la forme BD$variable il permet de cibler la colonne dans une base de données précise. On verra un peu plus tard qu’avec le paquet dplyron peut s’en affranchir. Dans ce cas, la réalisation de cette commande me donne 2 infos numericet vector. Un vecteur est juste la liste des données de l’age de tous les veaux (qu’on pourrait écrire c(5,3,2,3,3…)) On sait que ce vecteur est composé de variables numériques.

class(veaux$age)
## [1] "numeric"

La commande class() me donne ce qui compose ma variable age (des nombres).

appartée sur les classes variables dans R

C’est un peu compliqué si on va dans le détail donc en gros il y a des variables numériques (que l’on peut par la suite classer en integer, double). La classification integer prend moins de place car ne tient pas compte de la virgule et peut être spécifiée en faisant suivre le nombre de L ex 3L… MAIS je vous dirais que par défaut dans la plupart des analyses que je fais j’utilise la variable double qui stocke la virgule (jusqu’à présent je n’ai jamais eu besoin d’integer)…

Les variables de types character qui sont du texte, et que l’on peut définir plus spécifiquement en factor ou variables de classes, enfin les variables de type Booléen TRUE/FALSE que l’on appelle logical

Je vous renvoie à des textes plus spécifiques si cela vous intéresse concernant les structures et types de données. C’est toujours quelque chose à bien penser lorsque vous codez vos bases de données et aussi de bien l’intérioriser lors de vos analyses subséquentes.

4.1 Opérateurs dans R

Il existe différents opérateurs de base ou opérateurs booléens (réponse FALSE/TRUE) que je vais lister:

<- attribuer / assigner une valeur (équivalent à =)

<ou <= inférieur ou inférieur à égal (>et >= pour l’inverse)

== parfaitement égal à

!= non égal à

| ou / OR

& et/and

xor(a,b) est ce qu’exactement une des condition a ou b est vraie?

a%in%c(a,b,c) : est ce que a est présent dans une liste, vecteur…

all(a,b,c) est-ce que toutes les conditions a,b,c… sont satisfaites?

any(a, b, c, ...) est ce qu’au moins une condition a, b,c… est satisfaite…

Ce sont les principales dont on peut avoir à se servir au jour le jour…

4.2 Transformation des données basiques

4.2.1 Changer une donnée codée en 0/1 en une donnée catégorique ou de classe

head(veaux, 2)  # NB vous pouvez aussi demander à regarder les données par la fin en mentionnant : tail(BD) le défaut vous donne les 6 dernière lignes sinon vous ajustez avec n=...
## # A tibble: 2 x 14
##    case   age breed   sex  attd  dehy   eye  jnts  post pulse  resp  temp   umb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  1670     5     1     1     2  12      NA     0     2    NA    NA  37.6     0
## 2  8124     3     2     0     1  13.5     0     0     0   130   120  39.2     0
## # ... with 1 more variable: sepsis <dbl>

On voit bien ici que certaines variables sont codées en chiffre alors qu’elles ne sont pas numériques. La variable sex par exemple est une de ces variables. Supposons que 1=femelle et 0=male. Je ne peux décemment pas assumer que le format de cette variable me permette de faire des choses intelligentes par la suite… Pour ce faire je vais changer le format de cette variable (NB: je pourrais juste me contenter de ce que je fais ci-dessous et à la fin de renommer ma variable (le tout est que R reconnaisse que 0/1 n’est pas un chiffre)):

class(veaux$sex)
## [1] "numeric"
veaux$sex=as.factor(veaux$sex)
class(veaux$sex)
## [1] "factor"

C’est simple il faut juste donner la commande as. suivie du format que vous désirez. On voit maintenant que la variable sex est une variable de class ou factor . J’utilise à dessin les alternances de = et <-qui ont le même sens dans le code (pour faire <- le raccourci Alt + touche moins peut être utilisée). Le sens du = équivaut à attribuer la valeur de… Il est différent du code pour trouver une variable égale à une valeur ou un terme. On utilise alors ==.

Notez que j’aurai pu créer une toute nouvelle variable en la nommant par exemple sex_class:

veaux$sex_class=as.factor(veaux$sex)
class(veaux$sex_class)
## [1] "factor"
length(veaux$sex_class)
## [1] 254
summary(veaux$sex_class)
##    0    1 NA's 
##  121  131    2

C’est une nouvelle variable que j’ai créée avec 254 lignes…

4.2.2 Remplacer des données dans une liste de variables

C’est bien beau de transformer le format de la variable sex mais elle est toujours encodée en 0/1. J’aimerai donc bien remplacer ces chiffres par male/femelle.

Pour ce faire, rien de plus simple (plusieurs possibilités meth1, meth2, meth3…(on verra une autre méthode avec la suite tidyverse)):

Méthode 1:

#la possibilité vieille école

veaux$sex_meth1 <- ifelse(is.na(veaux$sex), "NA", ifelse(veaux$sex=="1", "Femelle", "Male" ))
table(veaux$sex_meth1)
## 
## Femelle    Male      NA 
##     131     121       2
table(veaux$sex)
## 
##   0   1 
## 121 131
#methode pour demander un tableau et m'assurer que tout est bien codé...

J’ai introduit a fonction ifelsequi se compose de 3 arguments

(1=test conditionnel, réponse si test conditionnel=VRAI, autre réponse si le test est faux)

(si sex==1, alors c’est une “femelle”, sinon c’est une “Mâle”)

2 autres choses à noter : 1- dans ma première condition je m’assure que ce soit bien codé pour garder mes données manquantes comme données manquantes… (sinon par défaut mon ifelse va coder mes NA avec le dernier argument … (ici Male…)) 2- == dans une commande pour reconnaitre une valeur la notation,.

Méthode 2:

veaux$sex_meth2 <- veaux$sex
levels(veaux$sex_meth2) #ici je regarde mes niveaux de ma variables catégorique
## [1] "0" "1"
levels(veaux$sex_meth2)=c("Male", "Femelle") # je réattribue à ces niveaux (toujours classés par défaut par ordre croissant ou par ordre alphabétique)
# le code dit: c("0","1) à remplacer par c("Male", "Femelle")


table(veaux$sex_meth2) # je vérifie que j'ai bien le bon code 
## 
##    Male Femelle 
##     121     131
summary(veaux$sex_meth2) #NB ici on voit que la table ne rapporte pas les données manquantes (à garder en tête...)
##    Male Femelle    NA's 
##     121     131       2

Méthode 3:

veaux$sex_meth3 <- ifelse(veaux$sex=="0","Male", "Femelle")
summary(veaux$sex_meth3)
##    Length     Class      Mode 
##       254 character character
# par défaut mes nouveaux niveaux de male et femelle sont reconnus comme "character" donc je m'assure de bien remettre le niveau de ma nouvelle variable comme étant une variable de type "factor"
veaux$sex_meth3 <- as.factor(veaux$sex_meth3)
summary(veaux$sex_meth3)
## Femelle    Male    NA's 
##     131     121       2

Il y aurait plein d’autres façons de coder cela mais ce n’est pas le but du tutoriel… Si vous voulez vous amuser il y a plein de subtilités que je vous laisse découvrir… Notez que dans tous les cas j’ai créé des nouvelles variables afin de garder ma variable initiale pour comparer. On aurait pu aussi directement réattribuer le même nom à notre variable finale. Néanmoins, la sécurité et la possibilité de comparer par rapport à l’original est une bonne pratique pour que vous vous assuriez de garder une trace que votre codage a du sens…

Sans plus tarder je vais parler des outils données de la suite tidyverse et du package dplyr pour nous simplifier la vie… Là on arrive dans du concrêt et du plus facile à vivre au jour le jour…

UNE BONNE PRATIQUE: TOUJOURS VÉRIFIER QUE VOTRE RECODAGE EST VALIDE EN VISUALISANT LES CONSÉQUENCES DE VOTRE CODE.

4.3 Présentation de la “pipe” %>% et des bases du langage dplyr

Jusqu’à présent on était assez limité avec des noms de variables à réécrire en long en référant tout le temps à la BD mère (eg BD$variable).

La librairie dplyret la notion de BD tidyont révolutionné R (en tout cas c’est ce qui m’a convaincu…). On a principalement parlé des BD sous la forme classique de R qui est une dataframe (grosso modo une matrice de lignes et de colonnes…). Le package dplyrs’appuie sur des données tidy ou organisées (je ne m’étendrai pas là dessus) mais on peut aussi l’utiliser sur une dataframe classique. La BD tidy va donner une tibble (format spécial de table) lorsqu’utilisée et entrée avec le paquet dplyr.

Ce qui est révolutionnaire dans ce paquet est l’utilisation de verbes pour créer des variables, les filtrer, les classer. En outre, il introduit la notion de “pipe” %>%, ce symbole (raccourci: CTL+flèche montante) est mis pour créer une chaine d’ordre et limite la longueur du code (pour les chaines les plus longues) et surtout est plus facile à lire lorsque vous le codez ou que vous le relisez…

Exemple : a %>% b %>% c : prend a et puis (ou then) applique lui b et puis applique à ce résultat c : comme c’est une chaîne, vous spécifiez la BD en partant puis vous ajoutez des demandes sans respécifier la BD…

Prenons un cas concrêt dans notre BD veaux. Nous avons une autre variable jnts joints ou articulations…

# comment connaitre la composition de cette variable?
table(veaux$jnts) #chaine sans pipe
## 
##   0   1   2   4 
## 216  21   5   1
# en dplyr
veaux %>% select(jnts) %>% table() #chaine pipe
## .
##   0   1   2   4 
## 216  21   5   1
summary(veaux$jnts)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   0.000   0.000   0.000   0.144   0.000   4.000      11

Ici j’ai sélectionné la variable jnts dans ma BD (avec le verbe select) puis j’ai fait une table. En voyant la longueur du code je n’ai pas amélioré significativement mon codage car la séquence avec la %>%est plus longue…. La pipe n’est pas magique lorsque la demande est courte mais on va gagner plus la séquence est longue (le code est plus compact et on a moins de risques d’erreur)

%>% dans R Source

Supposons maintenant que je veuille renommer la variable jntsen joints1 et joints2 respectivement en fonction de la séquence de codage et que je veuille regrouper les codes 0-1-2-4 en Nonevs more1(0 articulation atteinte vs 1 ou plus)

#code sans la pipe
veaux$joints1 <- as.factor(veaux$jnts)
veaux$joints1 <- ifelse(veaux$joints1=="0","None", "more1")
#verif1
table(veaux$joints1, veaux$jnts)
##        
##           0   1   2   4
##   more1   0  21   5   1
##   None  216   0   0   0
#verif2
sum(is.na(veaux$joints1))==sum(is.na(veaux$jnts)) #façon de m'assurer que j'ai le même nombre de données manquantes dans ma transformation (argument is.na(x) répond TRUE ou FALSE pour chacune des données de la liste... en faisant la somme avant et après transformation c'est pour vous montrer comment vérifier...) 
## [1] TRUE
#avec la pipe
veaux %>% 
  mutate(joints2=case_when(is.na(jnts)~"NA", jnts=="0" ~"None", TRUE~"more1")) 
## # A tibble: 254 x 20
##     case   age breed sex    attd  dehy   eye  jnts  post pulse  resp  temp   umb
##    <dbl> <dbl> <dbl> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  1670     5     1 1         2  12      NA     0     2    NA    NA  37.6     0
##  2  8124     3     2 0         1  13.5     0     0     0   130   120  39.2     0
##  3  6954     2     3 1         2  NA       1     0     2    NA    NA  NA       1
##  4  2737     3     4 1         1   5       0     0     0   132    40  38.6     0
##  5  5341     3     5 0         1   0       0     0     1   128    48  38.6     1
##  6  6749    10     6 0         1   5.5     0     0     0   160    48  39.6     0
##  7  3234     4     7 0         2   7       0     1     2   180    84  39       1
##  8  2325    14     8 0         1   7       0     0     0   100    20  35       0
##  9  2925     4     9 0         1   5       0     0     0   150    52  39.5     0
## 10  7108     8     1 0         2  10       0     0     2   120    68  37.8     0
## # ... with 244 more rows, and 7 more variables: sepsis <dbl>, sex_class <fct>,
## #   sex_meth1 <chr>, sex_meth2 <fct>, sex_meth3 <fct>, joints1 <chr>,
## #   joints2 <chr>
  #mutate est un verbe pour créer une nouvelle variable voir plus bas.
#je me sers de l'argument case_when qui est proche de ifelse mais fonctionne de façon plus large et est s'effectue avec des conditions multiple vs ifelse... le TRUE de la fin est équivalent à "ELSE" (donc la valeur associées si les liens logiques précédents ne sont pas respectés...)
#ici je dis: garde mes données manquantes telles quelles. si jnts=0 attribue None, sinon(donc si jnts n'est ni NA ni 0, met more1)
#j'aurai pu me servir de ifelse... mais il aurait fallu que je mette plusieurs ifelse ...
# ifelse(condition, ifelse(condition, si oui a, si non b), dernière portion...)

Vous l’avez vu et le verrez, comme dans toutes les bases de données, les données manquantes doivent toujours être bien évaluées et regardées dans vos codes afin de vous assurer que vous ne les transformiez pas par mégarde (impact +++ si vous en avez beaucoup…)

Donc vérifiez à chaque transformation que votre code fonctionne

Autre idées de lecture sur le sujet pas mal mieux expliqué que par moi ;-)

4.4 filter, select, arrange

4.4.1 Sélection d’un sous groupe de variable d’une table avec select

Lorsque vous avez une base de données vous pouvez soit sélectionner un sous ensemble des variables parmi celles enregistrées (une sélection par exemple dans la base de données veaux on pourrait s’intéresser à des variables spécifiques et en délaisser d’autres non utiles. On va alors utiliser select.

Supposons que je veuille regarder uniquement les variables prédéfinies car j’ai beaucoup de données que je n’utilise pas…

veaux_1 <- veaux %>% select(age, jnts, sex, breed) # je crée ma table avec juste 4 variables
head(veaux_1, n=3)
## # A tibble: 3 x 4
##     age  jnts sex   breed
##   <dbl> <dbl> <fct> <dbl>
## 1     5     0 1         1
## 2     3     0 0         2
## 3     2     0 1         3

Je peux aussi éliminer des variables non souhaitées

veaux_2 <- veaux %>% select( -age, -breed, -sex, -jnts) #je mets un moins devant mes variables à éliminer
head(veaux_2, n=3)
## # A tibble: 3 x 15
##    case  attd  dehy   eye  post pulse  resp  temp   umb sepsis sex_class
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl> <fct>    
## 1  1670     2  12      NA     2    NA    NA  37.6     0      0 1        
## 2  8124     1  13.5     0     0   130   120  39.2     0      0 0        
## 3  6954     2  NA       1     2    NA    NA  NA       1      1 1        
## # ... with 4 more variables: sex_meth1 <chr>, sex_meth2 <fct>, sex_meth3 <fct>,
## #   joints1 <chr>
# je peux aussi sélectionner par numéros de variables

veaux_3 <- veaux %>% select(1:6)
head(veaux_3, n=3)
## # A tibble: 3 x 6
##    case   age breed sex    attd  dehy
##   <dbl> <dbl> <dbl> <fct> <dbl> <dbl>
## 1  1670     5     1 1         2  12  
## 2  8124     3     2 0         1  13.5
## 3  6954     2     3 1         2  NA

Je pourrai aussi selectionner des variables contenant le même radical dans leur nom…

Bref, vous comprenez le principe. Pour plus d’infos voir le chapitre d’Hadley Wickham.

4.4.2 Sélection d’un sous groupe d’animaux ou de données selon des critères préétablis avec filter

Si on veut ne s’intéresser qu’à un certain nombre de lignes (ex éliminer les animaux d’un age particulier ou avec un critère par rapport à une ou 2 variable (ex ne garder que les veaux males de moins de 7j)) => on utilise alors le verbe filter .

#imaginons que je veuille garder uniquement les veaux mâles de moins de 7j...

veaux_m7 <- veaux %>% filter(age<=7 & sex_meth1=="Male") # je pourrais aussi utiliser d'autres conditions telles que ou | ou sauf !...
head(veaux_m7, n=10)
## # A tibble: 10 x 19
##     case   age breed sex    attd  dehy   eye  jnts  post pulse  resp  temp   umb
##    <dbl> <dbl> <dbl> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  8124     3     2 0         1  13.5     0     0     0   130   120  39.2     0
##  2  5341     3     5 0         1   0       0     0     1   128    48  38.6     1
##  3  3234     4     7 0         2   7       0     1     2   180    84  39       1
##  4  2925     4     9 0         1   5       0     0     0   150    52  39.5     0
##  5  1294     6     1 0         0   3       0     0     0   100    20  40       0
##  6  8476     2     1 0         1  12       0     0     1    80    16  34.1     0
##  7  4957     7     1 0         2  10       0     0     2   100    40  35       0
##  8  9178     2     1 0         1   7.5     0     0     0   120    NA  36       0
##  9  5119     7     1 0         1   4       0     0     0   180    36  39.7     0
## 10  1362     2     1 0         1   8       0    NA     2   110    50  37.5     0
## # ... with 6 more variables: sepsis <dbl>, sex_class <fct>, sex_meth1 <chr>,
## #   sex_meth2 <fct>, sex_meth3 <fct>, joints1 <chr>
dim(veaux_m7) # 58 veaux sont des mâles de moins de 7j...
## [1] 58 19

Notez que je peux toujours tout compacter pour sélectionner et filtrer selon la même chaine de code: ex BD %>% select () %>% filter() %>% autre portion de code… ca permet de mettre le tout de façon assez compacte et explicite…

pour des notions plus avancées et extensives je vous réfère au chapitre d’Hadley Wickham concernant l’utilisation de filter

4.4.3 Ordonner une base de données selon des variables avec la fonction arrange

La BD que vous avez pour vos analyses est rarement classée de façon pré-établie. C’est souvent une BD qui est classée en fonction de votre entrée de données. On peut avoir besoin de trier cette BD selon des critères pré-établis mais aussi pour tester une portion de recodage de données (ie voir si les max ou min d’une variable font du sens…)

On utilisera alors la fonction arrange qui est l’équivalent SAS de PROC SORT.

exemple: je veux ordonner ma BD selon l’age des veaux et leur déshydratation (variale dehy)

veaux %>% arrange(age, dehy) %>% head(n=20)
## # A tibble: 20 x 19
##     case   age breed sex    attd  dehy   eye  jnts  post pulse  resp  temp   umb
##    <dbl> <dbl> <dbl> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  4870     1     9 0         1   0       0     0     0   112    48  39.3     1
##  2  1589     1     7 1         2   3       0     1     2   140    52  39.7     1
##  3  1576     1     3 1         1   4       0     0     0    84    56  38.6     0
##  4  3468     1     8 0         1   8      NA     0     1   120    40  36.5     1
##  5  1725     1     3 1         1   9       0     0     1   120    48  38       0
##  6  1591     1     1 1         1  10       0     0     2   129    27  36.5     1
##  7  1740     1     3 1         2  10       0     0     1   140    76  39       1
##  8  8722     1     7 1         1  10       0     0     1   100    48  36.2     0
##  9  3082     1     8 1         1  13.5     0     0     2   120    32  37.5     0
## 10  3261     2     2 1         1   0       0     0     0   160    44  38.7     0
## 11  1490     2     8 1         0   0       0     0     0   120    54  39.2     0
## 12  4868     2     8 1         1   2       0     0     0    96    40  39.5     0
## 13  4709     2     8 1         1   4       0     2     1   120    44  38.7     1
## 14  4869     2     9 0         0   5       0     0     0   140    30  39.3     0
## 15  7291     2     8 1         2   6       0     0     2    90    20  39.2     0
## 16  9178     2     1 0         1   7.5     0     0     0   120    NA  36       0
## 17  1362     2     1 0         1   8       0    NA     2   110    50  37.5     0
## 18  1518     2     3 1         1   8       0     0     1   120    80  39.5     1
## 19  4871     2     2 1         1   9       0     0     1   160    70  38       1
## 20  2598     2     4 0         2   9       0     0     2    64    40  37       0
## # ... with 6 more variables: sepsis <dbl>, sex_class <fct>, sex_meth1 <chr>,
## #   sex_meth2 <fct>, sex_meth3 <fct>, joints1 <chr>

La BD est organisée avec les veaux d’abord classés par age puis par déshydratation…

Pour les variables numériques le classement s’effectue de façon explicite (plus petit au plus grand). Si vous voulez le faire par ordre décroissant: arrange(desc(var))devra être spécifié (NB: desc pour descending).

Pour les variables de types non numériques (ex facteur ou character), le classement se fait par défaut par ordre alphabétique.

#NB ici j'ai sélectionné des données pour que ce soit plus facile à voir sur la même page...
# je peux préciser quel est mon référent dans ma BD


veaux %>% select(age, dehy, sex_meth1, pulse) %>% arrange(sex_meth1, age) %>% head(n=10)
## # A tibble: 10 x 4
##      age  dehy sex_meth1 pulse
##    <dbl> <dbl> <chr>     <dbl>
##  1     1  10   Femelle     129
##  2     1   4   Femelle      84
##  3     1   9   Femelle     120
##  4     1  10   Femelle     140
##  5     1  10   Femelle     100
##  6     1   3   Femelle     140
##  7     1  13.5 Femelle     120
##  8     2  NA   Femelle      NA
##  9     2  12   Femelle     133
## 10     2   0   Femelle     160

Comment je fais si je veux mettre par défaut les mâles en premier? On doit aborder une nouvelle commande qu’on va détailler après: la fonction mutate qui équivaut à définir une nouvelle variable ou en modifier une existante (voir ci-dessous dans le point 4.5)

#je dois définir l'ordre des niveaux de ma variable
#en spécifiant que je force Male comme référent

veaux %>% mutate(sex_meth1=factor(sex_meth1, levels=c("Male", "Femelle"))) %>% 
   select(age, dehy, sex_meth1, pulse) %>% arrange(sex_meth1, age) %>% head(n=10)
## # A tibble: 10 x 4
##      age  dehy sex_meth1 pulse
##    <dbl> <dbl> <fct>     <dbl>
##  1     1   8   Male        120
##  2     1   0   Male        112
##  3     2  12   Male         80
##  4     2   7.5 Male        120
##  5     2   8   Male        110
##  6     2  15   Male        132
##  7     2  10   Male        130
##  8     2  15   Male         90
##  9     2  10   Male        120
## 10     2  10   Male        120

Notez que je peux classer selon toute une chaine de variables et aussi la plasciticité du code qui me permet de tout mettre en chaine avec la %>%

4.5 mutate, summarise

4.5.1 Définir une nouvelle variable par l’action mutate

Cette fonction permet de définir des variables nouvelles à partir d’autres par exemple, admettons que je veuille retrancher à la fréquence cardiaque pulse sa moyenne (centrer la variable). J’appelle cette variable pulse_cet sa cousine pulse_c2issue d’une même commande sans le verbe mutate.

veaux %>% mutate(pulse_c=pulse-mean(pulse, na.rm=TRUE)) %>% select(pulse_c, pulse) %>% head(n=10)
## # A tibble: 10 x 2
##    pulse_c pulse
##      <dbl> <dbl>
##  1   NA       NA
##  2   14.1    130
##  3   NA       NA
##  4   16.1    132
##  5   12.1    128
##  6   44.1    160
##  7   64.1    180
##  8  -15.9    100
##  9   34.1    150
## 10    4.11   120
#si dessous approche standard...
veaux$pulse_c2=veaux$pulse- mean(veaux$pulse, na.rm = TRUE)
head(veaux, n=10)
## # A tibble: 10 x 20
##     case   age breed sex    attd  dehy   eye  jnts  post pulse  resp  temp   umb
##    <dbl> <dbl> <dbl> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##  1  1670     5     1 1         2  12      NA     0     2    NA    NA  37.6     0
##  2  8124     3     2 0         1  13.5     0     0     0   130   120  39.2     0
##  3  6954     2     3 1         2  NA       1     0     2    NA    NA  NA       1
##  4  2737     3     4 1         1   5       0     0     0   132    40  38.6     0
##  5  5341     3     5 0         1   0       0     0     1   128    48  38.6     1
##  6  6749    10     6 0         1   5.5     0     0     0   160    48  39.6     0
##  7  3234     4     7 0         2   7       0     1     2   180    84  39       1
##  8  2325    14     8 0         1   7       0     0     0   100    20  35       0
##  9  2925     4     9 0         1   5       0     0     0   150    52  39.5     0
## 10  7108     8     1 0         2  10       0     0     2   120    68  37.8     0
## # ... with 7 more variables: sepsis <dbl>, sex_class <fct>, sex_meth1 <chr>,
## #   sex_meth2 <fct>, sex_meth3 <fct>, joints1 <chr>, pulse_c2 <dbl>

Notez bien: Rest sensible aux données manquantes. Par défaut dès que vous voulez calculer quelque chose assurez vous que vous mettez l’option na.rm=TRUE.

Parfois vous voulez juste laisser le nom à la variable que vous créer sans la changer (ex temperature en fahreneit vs celsius) on utilise alors transmute.

Sites spécifiques adressant la fonction mutateet transmute Chapitre d’Hadley Wickham

Feuillet spécifique dplyr ainsi que des exemples plus spécifiques

4.5.2 Summarize/Group_by

Très souvent on veut, calculer des fonctions dans des sous groupes (par exemple, je voudrais savoir quelle est la fréquence cardiaque en fonction de l’age et du sexe de mes veaux). Dans ce cas là on va utiliser 2 fonction qui sont trop cool: il s’agit de group_byet summarize (NB summariseet summarize sont acceptés). Pour calculer la fréquence cardiaque en fonction de l’âge, je vais d’abord grouper mes veaux par age et demander la moyenne…

veaux %>% group_by(age) %>% summarise(moy_fc=mean(pulse, na.rm=TRUE), Nombre_veaux=n())
## # A tibble: 28 x 3
##      age moy_fc Nombre_veaux
##    <dbl>  <dbl>        <int>
##  1     1   118.            9
##  2     2   116.           25
##  3     3   129.           15
##  4     4   133.            7
##  5     5   123.           17
##  6     6   116.           13
##  7     7   118.           35
##  8     8   114            18
##  9     9   114.           11
## 10    10   126            14
## # ... with 18 more rows
#notez ici que summarise vous permet de créer des variables à partir de stats inclues dans R... je peux nommer mes variables (une bonne pratique est toujours de mettre le nombre de données n() dans votre table car cela permet de vous assurer que votre code a du sens...)

TRÈS PRATIQUE QUAND ON VEUT CALCULER DES DONNÉES AGRÉGÉES (VACHES OU VEAUX PAR TROUPEAUX…)

**Je peux aussi agréger par plusieurs variables (group_by(ferme, lactation, vache…)

voir le référent dplyr

Jusqu’à présent j’ai présenté principalement les grandes orientations de dplyr (des verbes pour transformer et manipuler des données).

Pour la suite à vous de jouer!!!

4.6 Fusion de tables

Quelque chose d’important que je me dois de vous mentionner est la façon de fusionner ou joindre des tables. On veut souvent fusionner des variables au niveau animal (fichier individuel) à des données d’un niveau hierarchique supérieur (ex: régie de ferme).

On doit être capable de fusionner ces informations afin de les gérer dans une même BD. Dans l’univers tidyverse on va utiliser les fonctions se rapportant au radical _join.

Note: Dans l’univers R classique on utiliserai la fonction merge.

Il est très important de savoir comment fonctionne la jointure afin de bien sélectionner le type de join qui vous intéresse:

Je n’irai pas dans le détail MAIS

DÉFINIR LES VARIABLES QUI SONT DES CLÉS D’APPARIEMENT (key)

La fonction de jointure nécessite un appariement selon une ou plusieurs clés (ex identifiant de ferme et de veaux utilisé pour apparier une BD). Voir chapitre d’Hadley Wickham

Autre point fondamental:

Il existe des jointures qui apparient uniquement les données qui matchent parfaitement les données de chaque table (fonction inner_joint). Prenons l’exemple concret:

#imaginons un fichier contenant x1, et y, qui sont 2 variables de ferme
data_ferme <- data.frame(ferme=c("1", "2", "3", "4"), x1=c(1, 2, 3, 4), y=c(2:5))
# une base de données au niveau veaux qui contient une variable ferme notée farm
data_veau <- data.frame(farm=c("2", "2", "3", "4", "4", "5"), x2=c(1:6), x3=c(3:8))

4.6.1 Illustration inner_join

data_ferme %>% inner_join(data_veau, c("ferme"="farm"))
##   ferme x1 y x2 x3
## 1     2  2 3  1  3
## 2     2  2 3  2  4
## 3     3  3 4  3  5
## 4     4  4 5  4  6
## 5     4  4 5  5  7

QQ choses à noter: la ferme 1 et 5 ont disparu car pas présente dans les 2 BD…

*Noter aussi que je peux apparier même si les variables ne sont pas nommées de façon identique (je force les choses par c(clé BD gauche=clé BD droite))

4.6.2 Illustration left_join

Ici on va forcer à garder toutes les données de la BD de gauche même si il n’y a pas d’équivalent à droite… (ex des fermes ont participé au questionnaire mais n’ont pas fourni de données dans la BD veaux…)

data_ferme %>% left_join(data_veau, c("ferme"="farm"))
##   ferme x1 y x2 x3
## 1     1  1 2 NA NA
## 2     2  2 3  1  3
## 3     2  2 3  2  4
## 4     3  3 4  3  5
## 5     4  4 5  4  6
## 6     4  4 5  5  7

Ici on voit que les variables x2et x3 ne sont pas présentes pour la ferme 1. Elles sont remplacées par des NAdans la base jointe.

On peut en déduire la fonction right_join (c’est très proche)

4.6.3 Illustration de la jointure totale full_joint

data_ferme %>% full_join(data_veau, c("ferme"="farm")) %>% head(n=7)
##   ferme x1  y x2 x3
## 1     1  1  2 NA NA
## 2     2  2  3  1  3
## 3     2  2  3  2  4
## 4     3  3  4  3  5
## 5     4  4  5  4  6
## 6     4  4  5  5  7
## 7     5 NA NA  6  8

Ici on a a la fois gardé les données qui matchent la clé d’appariement (ferme 2, 3, 4), les clés absentes dans la BD data_veau (ferme 1) et celle absente de la BD data_ferme (ferme5).

Pour une vision plus détaillée des jointures et autres fonctionnalités pour combiner selon des critères plus spéciques on peut se référer à ce site.

4.7 Gestion des variables catégoriques ou facteurs

Pour ce chapitre je veux insister spécifiquement sur les données de classe dans R. Leur gestion est un peu moins intuitive pour moi que dans SAS où c’est plus simple à coder (Il faut bien que R ait des défauts !)

#imaginons cet exemple
#soit un score de boiterie absent, un peu, beaucoup, extrême (4 catégorie) 

score <- c("Un peu", "Beaucoup", "Un peu", "Extrême", "Absent")
class(score)
## [1] "character"
levels(score)
## NULL

Ici on voit que R n’a pas reconnu que score était un facteur, il ne reconnait donc pas ses niveaux (levels ). Un peu étrange… il aurait fallu que j’importe en précisant que c’était un facteur (ex avec score_c ou je me sers donc de factor())

score_c <- factor( c("Un peu", "Beaucoup", "Un peu", "Extrême", "Absent"))
levels(score_c)
## [1] "Absent"   "Beaucoup" "Extrême"  "Un peu"

On voit cependant que le classement s’est fait en fonction de l’ordre alphabétique (défaut).

NB: si je voulais préciser dans une table que j’importe qu’une variable est un facteur je dois juste mettre var=as.factor(var)

score_c=factor(score_c, levels=c("Absent", "Un peu", "Beaucoup", "Extrême"))
levels(score_c)
## [1] "Absent"   "Un peu"   "Beaucoup" "Extrême"

Ca marche!!!

On peut aussi spécifier le niveau de référence que l’on veut qui pourrait être spécifiée dans un modèle de régression par exemple ou pour spécifier les niveaux des variables catégoriques de référence. On utilisera alors la fonction relevel qui permet de spécifier le référent.

#imaginons que je veuille évaluer la boiterie par rapport au score Extreme

score_c <- relevel(score_c, ref="Extrême")
levels(score_c)
## [1] "Extrême"  "Absent"   "Un peu"   "Beaucoup"

On voit que j’ai spécifié mon “référent” …

CECI TERMINE LE 1ER TUTORIEL SUR LES BASES D’IMPORTATION DES DONNÉES ET DE MANIPULATION DE BASE

LE MIEUX EST MAINTENANT DE PRATIQUER AVEC VOS DONNÉES…

Pour toute information complémentaire ou bug à fixer