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 s.buczinski@umontreal.ca
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
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 R
un 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…
Bref, je pourrais en parler des heures durant… Mais le mieux est de vous faire votre propre idée… => ALLONS -Y!!!
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.
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…*
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.
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.
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. .
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:
# 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")
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) |
|
0 (0%) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | sex [numeric] | Min : 0 Mean : 0.5 Max : 1 |
|
2 (0.79%) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
5 | attd [numeric] | Mean (sd) : 1.1 (0.5) min < med < max: 0 < 1 < 2 IQR (CV) : 0 (0.5) |
|
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 |
|
18 (7.09%) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
8 | jnts [numeric] | Mean (sd) : 0.1 (0.5) min < med < max: 0 < 0 < 4 IQR (CV) : 0 (3.2) |
|
11 (4.33%) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
9 | post [numeric] | Mean (sd) : 0.9 (0.8) min < med < max: 0 < 1 < 2 IQR (CV) : 2 (0.9) |
|
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 |
|
11 (4.33%) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
14 | sepsis [numeric] | Min : 0 Mean : 0.3 Max : 1 |
|
0 (0%) |
Generated by summarytools 0.9.6 (R version 4.0.2)
2020-07-08
#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
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.
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.
Dans R
les variables ont toutes un des formats suivants:
À la base 3 formats de base des données dans R (on parle de vecteurs atomiques)
Vecteurs atomiques
Logical
TRUE vs FALSE ou aussi en abrégé T/FNumeric
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…))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…
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_csv2
qui 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_csv2
le read_csv
s’utilise pour les fichiers séparés par une “,”. enfin readr
me permet aussi de lire des fichiers texte séparés par une tabulation par read_tsv
pour 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
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 value
numé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 group
et 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). value
est une variable numérique…
vis_dat(essai)
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
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 (dbl
ou 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 dplyr
on peut s’en affranchir. Dans ce cas, la réalisation de cette commande me donne 2 infos numeric
et 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.
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…
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…
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 ifelse
qui 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.
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 dplyr
et la notion de BD tidy
ont 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 dplyr
s’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)
Supposons maintenant que je veuille renommer la variable jnts
en joints1
et joints2
respectivement en fonction de la séquence de codage et que je veuille regrouper les codes 0-1-2-4 en None
vs 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 ;-)
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.
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
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 %>%
…
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_c
et sa cousine pulse_c2
issue 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: R
est 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 mutate
et transmute
Chapitre d’Hadley Wickham
Feuillet spécifique dplyr ainsi que des exemples plus spécifiques
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_by
et summarize
(NB summarise
et 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!!!
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))
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))
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 x2
et x3
ne sont pas présentes pour la ferme 1. Elles sont remplacées par des NA
dans la base jointe.
On peut en déduire la fonction right_join
(c’est très proche)
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.
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 s.buczinski@umontreal.ca
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…