Préparation des données

Un article de IMSP - Formation continue.

Préparer les données de terrain pour l'analyse est l'une des tâches qui demande le plus de resources et de temps au quotidien. Il existe une grande variété d'outils aptes à cette tâche, et même dans certaines conditions les éditeurs et traitements de texte peuvent s'avérer utiles. Nous décrivons ici quelques procédures simples avec R et STATA. En effet, il est important de réaliser les tâches selon des méthodes documentées et aisément vérifiables: la reproductivité des opérations de gestion de données (transferts, recodage, création de nouvelles variables) contribue à la transparence scientifique et est une exigence de plus en plus présente. Le scripting ou programmation des opérations est souhaitable, un sujet abordé dans le prochain chapitre. Les exemples sont pris d'un cas réel.

Tableau synoptique:

opération STATA R
remplacer une valeur dans une variable source('gsr.r')
quart <- test001$X.QUARTIER
quart <- gsr(quart,"OONAH","FONAH")
etc.
quart <- as.factor(quart)

test001$X.QUARTIER <- quart

renommer les variables nouveaux.noms <- c("quartier","ddn","sexe","p1ph1",
"p1ph2","p1ptemp","p1prate","p1pge",
"p1pdenpf","p1pgam")

names(test001) <- nouveaux.noms

traiter les données manquantes thegam <- test001$p1pgam
thegam <- as.character(thegam)
thegam <- gsr(thegam,"",NA)
thegam <- as.factor(thegam)
test001$p1pgam <- thegam
etc.
convertir des dates myddn <- test001$ddn
myddn <- as.character(myddn)
myddn <-strptime(myddn,"%d.%m.%Y")
myddn.frame <- as.data.frame(myddn)
test001$ddn <- myddn.frame$myddn
save(test001,file = "test005.Rdata")
calculer un âge


Sommaire

Remplacer une valeur dans une variable

Reprenons le fichier test001: http://www.santepublique.org/fc/data/test001.csv déjà présenté dans analyse préliminaire avec R et STATA.

R

Chargeons le fichier

test001 <- read.csv('test001.csv')

Examen des données

names(test001)

résultat:

[1] "X.QUARTIER" "X.DDN"      "X.SEXE"     "X.P1PH1"    "X.P1PH2"
[6] "X.P1PTEMP"  "X.P1PRATE"  "X.P1PGE"    "X.P1PDENPF" "X.P1PGAM"

de quel type sont les variables?

str(test001)

résultat:

data.frame':   754 obs. of  10 variables:
 $ X.QUARTIER: Factor w/ 12 levels "FONAH","GOUNYAHOUN",..: 9 9 9 9 9 9 9 9 9 9 ...
 $ X.DDN     : Factor w/ 288 levels "01.01.1989","01.01.1990",..: 1 4 1 6 4 7 83 1 18 24 ...
 $ X.SEXE    : Factor w/ 2 levels "F","M": 2 2 1 2 1 1 1 1 1 2 ...
 $ X.P1PH1   : int  34 30 35 45 36 37 35 35 35 25 ...
 $ X.P1PH2   : int  37 28 35 48 36 36 42 38 35 29 ...
 $ X.P1PTEMP : num  37 36.4 37.1 37.2 37 37.2 36.2 37.2 36.6 37.5 ...
 $ X.P1PRATE : int  0 0 0 0 0 0 0 0 0 0 ...
 $ X.P1PGE   : Factor w/ 3 levels "","N","Y": 2 3 3 2 3 3 3 3 2 3 ...
 $ X.P1PDENPF: int  0 33400 150 0 250 100 400 100 0 9600 ...
 $ X.P1PGAM  : Factor w/ 3 levels "","N","Y": 2 3 3 2 2 2 2 2 2 2 ...

La variable X.QUARTIER est considérée par R comme un facteur. Examinons-la:

levels(X.QUARTIER)
 [1] "FONAH"          "GOUNYAHOUN"     "LIANH"          "OONAH"
 [5] "OONDE"          "OOUNYAHOUN"     "SEREKENI"       "ZIANH"
 [9] "ZONDE"          "ZONDE kodeniko" "ZONDE Kodeniko" "ZONDE koko"

Plusieurs noms sont suspects de doublons:

  • GOUNYAHOUN (position 2) et OOUNYAHOUN (position 6)
  • OONDE (position 5) et ZONDE (position 9)
  • ZONDE kodeniko (position 9) et ZONDE Kodeniko (position 10) (élementaire...)
  • FONAH (position 1) et OONAH (position 4)
  • LIANH (position 3) et ZIANH (position 8)
Image:Fiat_lux.png En cas de doute, et chaque fois que cela semble possible, il est recommandé de tirer au clair toute ambiguité perçue avec les personnes qui ont mené l'enquête de terrain. Par exemple: est-ce que ZONDE kodeniko et ZONDE koko sont des dénominations du même endroit, ou bien s'agit-il de noyaux de peuplement différents?

examinons les effectifs:

length(X.QUARTIER) 
[1] 754

examinons le tableau des fréquences:

table(X.QUARTIER)
X.QUARTIER
         FONAH     GOUNYAHOUN          LIANH          OONAH          OONDE
           172             64              2              1              1
    OOUNYAHOUN       SEREKENI          ZIANH          ZONDE ZONDE kodeniko
             2             89             64            215             35
ZONDE Kodeniko     ZONDE koko
            30             79



Renseignements et contacts pris, on nous transmet le plan suivant. Le village de Serekeni est situé quant à lui à 7 Km. environ de Zonde.:



Il est décidé d'unifier GOUNYAHOUN et OUNYAHOUN, LIANH et ZIANH, OONAH et FONAH, et finalement ZONDE kodeniko et ZONDE Kodeniko. ZONDE koko constitue un noyau de population réel et bien distinct de Zonde kodeniko.

Modification des données

Nous allons utiliser une fonction très utile, et par la même occasion nous familiariser un peu plus avec le chargement de fonctions dans R. Global search and replace (Schwarz 2006) met en oeuvre la fonction interne replace(). Vous pouvez copier la fonction suivante et la coller dans un éditeur de texte. enregistrez-la dans un fichier que vous nommerez gsr.r

gsr <- function(Source, Search, Replace) {
  if (length(Search) != length(Replace)) stop("Search and Replace Must Have Equal Number of Items\n")
  Changed <- as.character(Source)
  for (i in 1:length(Search))
  {
    cat("Replacing: ", Search[i], " With: ", Replace[i], "\n") 
    Changed <- replace(Changed, Changed == Search[i], Replace[i])   }
    cat("\n")
 Changed
}

ou bien vous pouvez la télécharger et la placer dans votre répertoire de travail: http://www.santepublique.org/fc/data/gsr.r

Charger cette fonction en mémoire est ensuite très simple. Nous utilisons la commande source() qui permet d'exécuter des fichiers de code source:

source('gsr.r')

l'opération est silencieuse, vous pouvez vérifier que la fonction est bien présente:

gsr 

vous devriez voir s'afficher le code source de la fonction (vous pouvez consulter ainsi le code source de n'importe quelle fonction dans R).

Nous souhaitons modifier les données de la variable qui contient les noms de quartier. Nous en faisons d'abord une copie de travail:

quart <- test001$X.QUARTIER

vérifions:

> levels(quart)
 [1] "FONAH"          "GOUNYAHOUN"     "LIANH"          "OONAH"
 [5] "OONDE"          "OOUNYAHOUN"     "SEREKENI"       "ZIANH"
 [9] "ZONDE"          "ZONDE kodeniko" "ZONDE Kodeniko" "ZONDE koko"

nous alllons remplacer "OONAH" par "FOONAH":

>quart <- gsr(quart,"OONAH","FONAH")
 Replacing:  OONAH  With:  FONAH

"OONDE" par ZONDE:

> quart <- gsr(quart,"OONDE","ZONDE")
 Replacing:  OONDE  With:  ZONDE

exercice: à l'aide de la fonction gsr() remplacez "LIANH" par "ZIANH", "OOUNYAHOUN" par "GOUNYAHOUN" et "ZONDE Kodeniko" par "ZONDE kodeniko"

Il est temps de vérifier notre travail:

> levels(quart)
 NULL

Qu'est-il arrivé?

> str(quart)
 chr [1:754] "ZONDE" "ZONDE" "ZONDE" "ZONDE" "ZONDE" "ZONDE" ...

Nos facteurs initiaux ont été transformés en chaînes de caractères (à la ligne 4 de la fonction). Nous le changeons à nouveau en facteurs:

quart <- as.factor(quart)

tout rentre dans l'ordre:

> str(quart)
 Factor w/ 7 levels "FONAH","GOUNYAHOUN",..: 5 5 5 5 5 5 5 5 5 5 ...
>levels(quart)
 [1] "FONAH"          "GOUNYAHOUN"     "SEREKENI"       "ZIANH"
 [5] "ZONDE"          "ZONDE kodeniko" "ZONDE koko"


Les localisations correspondent désormais à la carte.

nous pouvons produire une table des fréquences:

> table(quart) 
quart
         FONAH     GOUNYAHOUN       SEREKENI          ZIANH          ZONDE
           173             66             89             66            216
ZONDE kodeniko     ZONDE koko
            65             79

nous avons maintenant sept quartiers avec entre 65 et 216 observations. Cela paraît satisfaisant, nous consignons les valeurs modifiées dans la table d'origine:

test001$X.QUARTIER <- quart

et nous ne manquons pas d'enregistrer notre fichier modifié avec un nouveau nom:

save(test001,file = "test002.Rdata")

STATA

en construction

Renommer les variables

R

Lors de l'importation des données depuis le fichier test001.csv (voir Analyse_préliminaire_avec_R_et_STATA#R_2 nous remarquons que le logiciel a modifié les noms des variables: passage en majuscules et ajout d'un X. devant l'ancien nom.

 >names(test001)
  [1] "X.QUARTIER" "X.DDN"      "X.SEXE"     "X.P1PH1"    "X.P1PH2"
  [6] "X.P1PTEMP"  "X.P1PRATE"  "X.P1PGE"    "X.P1PDENPF" "X.P1PGAM"

Imaginons que nous souhaitons revenir aux noms précédents. Nous allons créer un vecteur nouveaux.noms à l'aide de la fonction c() (comme "chaînage"):

nouveaux.noms <- c("quartier","ddn","sexe","p1ph1","p1ph2","p1ptemp","p1prate","p1pge","p1pdenpf","p1pgam")

puis nous assignons ces valeurs aux noms des variables:

names(test001) <- nouveaux.noms

vérifions:

>names(test001)
 [1] "quartier" "ddn"      "sexe"     "p1ph1"    "p1ph2"    "p1ptemp"
 [7] "p1prate"  "p1pge"    "p1pdenpf" "p1pgam"

N'oublions pas d'enregistrer notre fichier de données modifié:

save(test001,file = "test003.Rdata")

STATA

En construction

Traiter les données manquantes

Les données manquantes, qu'elles soient explicites ou masquées, sont un problème sérieux dans toute analyse statistique, notamment lorsque des tentatives sont faites pour leur attribuer une signification (imputation). "La source ultime de la plupart des données manquantes masquées est probablement l'absence de représentation standard des données manquantes" [1]. Nous devons être particulièrement attentifs lors de l'échange de donnéesentre différents logiciels, systèmes et usagers.

R

Dans ce logiciel, les données manquantes sont représentées par la valeur réservée NA. Il peut arriver, lors d'une importation de données, que les données manquantes ne soient pas correctement reconnues. Par exemple, notre objet test001 a été importé d'un fichier test001.csv

Nous rerpartons du fichier que nous avons enregistré dans l'exercice précédent:

load("test003.Rdata")
source('gsr.r')

Nous allons examiner un exemple: la variable dicothomique "X.P1PGAM" (présence ou absence de gamètocytes) dans l'objet test001.

str(test001$p1pgam)
Factor w/ 3 levels "","N","Y": 2 3 3 2 2 2 2 2 2 2 ...

Nous constatons que les données manquantes (champ vide) ont été interprétées comme un niveau, la variable apparait comme un facteur à trois niveaux. Ce n'est pas souhaitable. Nous copions notre variable dans un objet temporaire.

thegam <- test001$p1pgam

convertissons nos facteurs en chaînes de caractères:

thegam <- as.character(thegam)

remplaçons toutes les valeurs "" par des NA.

 thegam <- gsr(thegam,"",NA)
Replacing:    With:  NA

vérifions:

> thegam
  [1] "N" "Y" "Y" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "Y" "N"
 [19] "N" "N" "N" "Y" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "N" "Y" "N" "N"
 [37] "N" "N" "N" "N" "N" "N" "Y" "Y" "N" "N" "N" "N" "N" "N" "N" "N" "N" "Y"
 [55] "N" NA  NA  "N" "N" "N" "Y" "N" "Y" "N" "N" "N" "N" NA  "N" "N" "N" "N"
 etc.

nous convertissons à nouveau en facteur la variable et nous vérifions:

thegam <- as.factor(thegam)
 str(thegam)
Factor w/ 2 levels "N","Y": 1 2 2 1 1 1 1 1 1 1 ...

C'est bien ce qu'on voulait. Nous attribuons ces valeurs à la variable thegam de la table:

test001$p1pgam <- thegam

exercice: examiner d'autres variables de la table test001. Quelle autre variable présente exactement le même cas de figure? appliquez le traitement à cette variable.

Enregistrez le résultat de votre travail, vous l'utiliserez dans d'autres exercices:

save(test001,file = "test004.Rdata")

STATA

en construction

Traiter des dates

Il n'y a pour l'instant pas de consensus sur un format universel pour traduire les variables temporelles, il faut donc s'attendre à trouver les données temporelles dans des formats assez divers. La première mesure consiste à déterminer le format d'origine. Il faut ensuite le traduire dans la représentation interne des données temporelles du logiciel de statistiques utilisé. Dans un troisième temps on abordera des opérations telles que le calcul des âges.

R

Convertir des dates

Il faut s'attentre à voir arriver des dates dans les formats les plus divers. La première mesure consiste à déterminer lequel.

Le tableau test001 comporte une variable chronologique: ddn, qui représente la date de naissance des enfants examinés. Observons-la:

> str(test001$ddn)
 Factor w/ 288 levels "01.01.1989","01.01.1990",..: 1 4 1 6 4 7 83 1 18 24 ...
> head(test001$ddn) 
[1] 01.01.1989 01.01.1992 01.01.1989 01.01.1995 01.01.1992 01.01.1996
288 Levels: 01.01.1989 01.01.1990 01.01.1991 01.01.1992 ... 30.03.1996

Les dates de naissance ont été interprétées comme des facteurs, ce qui est faux. Nous établissons que le format d'origine est jour(deux décimales) . mois (deux décimales) . année (complète)

nous créons un objet de travail avec les dates à convertir:

myddn <- test001$ddn

nous convertissons nos facteurs en chaînes de caractères:

myddn <- as.character(myddn)

R est doté d'une fonction très puissante pour lire des dates: strptime(). Consultons l'aide:

Help(strptime)

Nous déterminons que la représentation correspondant à notre format de date est %d.%m%.Y Nous pouvons donc tenter la conversion:

myddn <- strptime(myddn,"%d.%m.%Y")

vérifions:

>str(myddn)
 'POSIXlt', format: chr [1:754] "1989-01-01" "1992-01-01" "1989-01-01" "1995-01-01" ...
> summary(myddn)
                      Min.                    1st Qu.
 "1988-01-15 00:00:00 CET"  "1992-10-15 00:00:00 CET"
                    Median                       Mean 
 "1995-04-19 00:00:00 CEST"  "1995-02-23 02:33:06 CET"
                   3rd Qu.                       Max.
 "1997-11-15 00:00:00 CET"  "2001-03-15 00:00:00 CET"

POSIXlt étant la représentation interne de temps de R. C'est ce que l'on voulait.

Avant de pouvoir assigner le contenu de notre nouvelle variable nous devons la transformer en table (pour contourner un affreux bogue):

myddn.frame <- as.data.frame(myddn)

vérifions:

> head(myddn.frame)
       myddn
1 1989-01-01 
2 1992-01-01 
3 1989-01-01
4 1995-01-01
5 1992-01-01
6 1996-01-01
...

nous pouvons maintenant assigner nos dates à la table d'origine:

test001$ddn <- myddn.frame$myddn

et nous enregistrons notre table:

save(test001,file = "test005.Rdata")

Calculer un âge

L'âge nous sera plus utile que la date de naissance. Nous allons calculer le calculer à la date du premier passage, le 3 mai 2001. Commençons par attribuer cette date à un objet:

passage1 <- "03.05.2001"

nous le convertissons en date POSIX à l'aide de la fonction strftime():

passage1 <- strptime(passage1,"%d.%m.%Y") 

et nous vérifions:

> str(passage1)
 'POSIXlt', format: chr "2001-05-03"

maintenant nous pouvons calculer l'âge comme la différence entre la date du passage et la date de naissance. Nous pourrions soustraire directement test001$ddn de passage1, mais nous aimerions avoir le contrôle sur toutes les options: nous utilisons donc la fonction difftime()

p1age <- difftime(passage1,test001$ddn,tz="",units="days") 

l'objet obtenu est du type "difftime", et l'unité le jour:

>str(p1age)
Class 'difftime'  atomic [1:754] 4505 3410 4505 2314 3410 ...
  ..- attr(*, "tzone")= chr ""
  ..- attr(*, "units")= chr "days"

A première vue, nous ne trouvons pas de fonctions qui permettent de traduire la durée des objets "difftime" en années+mois. Nous nous contenterons d'une approximation années+décimales. Attention toutefois avec des séries où l'âge est déterminé de façon plus précise que dans la présente! Il importe de s'interroger si une plus grande précision de calcul que annéés = jours / 365 a un sens ou non dans l'analyse.

nous convertissons l'objet temporel en objet numérique:

p1age <- as.numeric(p1age)

puis nous le convertissons en années+décimales:

p1age <- p1age / 365.25

vérifions:

> str(p1age)
 num [1:754] 12.34  9.34 12.34  6.34  9.34 ...

Histogrammes d'âges

nous pouvons désormais étudier le profil d'âges de l'échantillon d'enfants étudié:

>summary(p1age)
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  0.1341  3.4660  6.0440  6.1940  8.5530 13.3100
hist(p1age)

Image:P1age_hist_r.png

Nous avons d'autres possibilités pour l'analyse graphique. Installons l'extension Hmisc du professeur Frank E. Harrell (Vanderbilt University)

install.packages('Hmisc')  # une seule fois par installation
library('Hmisc')           # lors de la session

Nous allons utiliser la fonction histbackback(), illustrée dans la Gallerie de graphiques avec R, pour étudier la répartition par sexe et tranches d'âge de notre population. Il nous faut pour cela dichotomiser l'effectif par sexes à l'aide de la fonction split:

> agesex <- split(p1age,test001$sexe)
> str(agesex)
 List of 2
  $ F: num [1:384] 12.34  9.34  5.34  2.31 12.34 ...
  $ M: num [1:370] 12.34  9.34  6.34  1.50  2.31 ...

Nous pouvons générer maintenant un histogramme double et le colorier:

 out <- histbackback(agesex, brks=c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
 barplot(out$right, col="skyblue", horiz=TRUE, space=0, add=TRUE, axes=FALSE)
 barplot(-out$left, col="hotpink" , horiz=TRUE, space=0, add=TRUE, axes=FALSE)

Image:P1age_sexe_hist_r.png

On découvre d'intéressantes possibles différences dans les effectifs des classes d'âge selon le sexe. Nous reviendrons sur ce point.

Polygones et courbes de densité par âge

La construction de polygones de fréquences est une autre technique fréquemment utilisée pour comparer les distributions de fréquences. On obtient le polygone de fréquences en joignant le milieu des sommets des barres de l'histogramme des âges. Nous adaptons ici une technique publiée dans R graph gallery. La table agesex a été générée dans l'exercice précédent.

hf <- hist(agesex$F,breaks=c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14),prob=TRUE,plot=FALSE)
hm <- hist(agesex$M,breaks=c(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14),prob=TRUE,plot=FALSE)

exercice: inspectez les objets hm et hf ainsi générés. Que contiennent-ils?

Nous préparons les informations pour le tracé des polygones:

dbreaksm <-hm$mids[2] - hm$mids[1]
dbreaksf <-hf$mids[2] - hf$mids[1]
xxm <- c(hm$mids[1]-dbreaksm,hm$mids,tail(hm$mids,1)+dbreaksm)
xxf <- c(hf$mids[1]-dbreaksf,hf$mids,tail(hf$mids,1)+dbreaksf)
yym <- c(0,hm$density,0)
yyf <- c(0,hf$density,0)

Puis nous dessinons un histogramme (de la même couleur que le fond) et les deux polygones de fréquences:

hist(agesex$M,prob=TRUE,xlab="Age",main="Distribution par âges: F (rose) et M (bleu)",border="white",xlim=c(0,14))
lines(xxf,yyf,lwd=2,col="hotpink")
lines(xxm,yym,lwd=2,col="skyblue")

Image:Polygones_age_sexe.png

Nous pouvons tout aussi bien utiliser la fonction de calcul de densité, déjà abordée dans analyse graphique avec R et STATA#R_2, avec un abord plus simple:

hist(agesex$M,prob=TRUE,xlab="Age",main="Distribution par âges: F (rose) et M (bleu)",border="white",xlim=c(0,14))
lines(density(agesex$M), col='skyblue', lwd=3)
lines(density(agesex$F), col='hotpink', lwd=3)

Image:Densites_age_sexe.png

Image:Fiat_lux.png Quelle que soit la technique, un sous-effectif masculin dans les classes d'âge de 6 à 10 ans devient évident, et mérite d'être investigué par la suite. Parmi les causes possibles on peut imaginer:
  • un sous-échantillonnage en rapport à des facteurs culturels?
  • un sous-échantillonnage de mesure?
  • une sur-mortalité?
  • etc.

Ajouter l'âge à la table comme une nouvelle colonne

Nous allons créer une nouvelle table test002 qui incorpore la colonne p1age calculée dans les précédents exercices. Nous utiliserons pour cela la fonction data.frame() en passant comme arguments les noms des colonnes à créer dans l'ordre souhaité.

test002 <- data.frame(test001$quartier,test001$ddn,test001$sexe,p1age,test001$p1ph1,
test001$p1ph2,test001$p1ptemp,test001$p1pge,test001$p1pdenpf,test001$p1pgam) ;

vérifions:

> head(test002) ;
  test001.quartier test001.ddn test001.sexe     p1age test001.p1ph1
1            ZONDE  1989-01-01            M 12.342352            34
2            ZONDE  1992-01-01            M  9.342352            30
3            ZONDE  1989-01-01            F 12.342352            35
4            ZONDE  1995-01-01            M  6.339612            45
5            ZONDE  1992-01-01            F  9.342352            36
6            ZONDE  1996-01-01            F  5.339612            37
  test001.p1ph2 test001.p1ptemp test001.p1pge test001.p1pdenpf test001.p1pgam
1            37            37.0             N                0              N
2            28            36.4             Y            33400              Y
3            35            37.1             Y              150              Y
4            48            37.2             N                0              N
5            36            37.0             Y              250              N
6            36            37.2             Y              100              N    


On remarquera que la reconstitution d'une table par cette méthode incorpore la référence à la table d'origine dans les noms des variables. Nous souhaitons conserver nos anciens noms de variables:


names(test002) <- c("quartier","ddn","sexe","p1age","p1ph1","p1ph2","p1ptemp",
"p1pge","p1pdenpf","p1pgam") ;


Il est temps d'enregistrer le travail.

save(test002,file = "test002.Rdata") ;

STATA

en construction

Lectures recommandées

Pour continuer

Notions de base

  • Introduction
  1. Pourquoi R?
  2. Prise en main de R
  • Statistiques descriptives en pratique
  1. Analyse préliminaire avec R et STATA
  2. Analyse graphique avec R et STATA
  3. Préparation des données
  4. Automatiser le traitement des données
  5. Tabulations
  • Caractérisation des observations
  1. Les mesures de tendance centrale
  2. Les mesures de dispersion
  3. Tests de normalité
  4. Loi normale
  5. Les scores
  1. Intervalles de confiance
  2. La distribution de Khi-deux
  3. La distribution de Student
  4. Hypothèses et types d'erreur
  5. Valeurs de p
  6. Comparer deux moyennes
  7. Mesures appariées
  • Épidémiologie
  1. Les mesures de fréquence en épidémiologie
  2. Risque Relatif et Odds Ratio avec intervalles de confiance
  3. Test de khi-carré pour une table 2 x 2
  4. Test exact de Fisher
  5. Examens de dépistage, sensibilité, spécificité, valeur prédictive
  6. Mesures d'impact pour une exposition
  7. Épidémiologie des maladies transmissibles
  8. Confusion et modification d'effet
  9. Les types d'études
  10. Courbes de survie