Analyse graphique avec R et STATA

Un article de IMSP - Formation continue.

Il a souvent été affirmé qu'une image vaut mieux qu'un long discours. Certains aspects que nous avons vu dans analyse préliminaire avec R et STATA nous apparaissent beaucoup plus évidents et parlants lorsqu'ils sont présentés sous forme graphique. Nous en abordons ici les rudiments.

Tableau synoptique:

opération STATA R
configuration version 8.0 library(sma)
options(scipen=1000)
options(digits=3)
ouvrir le fichier de données use test001 load("test001.Rdata")
attach('test001')
histogramme histogram p1ph1,bin(17)
graph display Graph,margin(tiny) scheme(s1mono)
hist(test001$X.P1PH1, breaks=17, col="light blue")
diagramme quantile-quantile ("q-q plot"): comparaison à une distribution normale qnorm p1ph1, rlopts(lcolor(red))
graph display Graph, margin(tiny) scheme(s1color)
qqnorm(test001$X.P1PH1)
qqline(test001$X.P1PH1,
col="red",lwd=3)
diagramme quantile-quantile ("q-q plot"): comparaison entre deux distributions qqplot p1ph1 p1ph2, rlopts(lcolor(red))
graph display Graph, margin(tiny) scheme(s1color)
qqplot(test001$X.P1PH2,test001$X.P1PH1)
plot.qqline(test001$X.P1PH2,test001$X.P1PH1,
col="red",lwd=3)
stripchart N/A stripchart(test001$X.P1PH1,method="jitter",
xlim=c(20,55))
corrélation et régression (graphique) twoway (scatter p1ph2 p1ph1) (lfit p1ph2 p1ph1) (lfit p1ph1 p1ph2) plot(test001$X.P1PH2 ~ test001$X.P1PH1)
abline(lm(test001$X.P1PH2 ~ test001$X.P1PH1),col="red")
abline(lm(test001$X.P1PH1 ~ test001$X.P1PH2),col="blue")
corrélation et régression (coefficient, test et intervalles de confiance) correlate p1ph1 p1ph2
ou
pwcorr p1ph1 p1ph2, sig obs
cor(test001$X.P1PH1,test001$X.P1PH2, use="complete")
cor.test(test001$X.P1PH1,test001$X.P1PH2, alternative="two.sided",
method="pearson", conf.level= 0.98)
diagramme de Tukey ("boîte à moustaches") graph hbox p1ph2 p1ph1 boxplot(test001$X.P1PH1,test001$X.P1PH2, horizontal = TRUE, notch = TRUE,
col="light blue")


Sommaire

Configuration préalable

STATA

Version 8.0
use test001

R

Nous supposons que les extensions spécifiées dans analyse préliminaire avec R et STATA ont été installées. Dans ce cas il suffit de charger en mémoire celles qui nous seront nécessaires, et de configurer quelques paramètres d'affichage par défaut:

library(sma)
options(scipen=1000)
options(digits=3)

chargeons le fichier test001.Rdata produit dans la session précédente:

load("test001.Rdata")
objects()

réponse:

[1] "test001"

avec la fonction attach() nous incorporons l'objet test001 comme objet par défaut: nous n'aurons en principe plus besoin de préciser le nom de l'objet dans le nom des variables: test001$X.P1PH1 peut alors être identifiée comme test001$X.P1PH1 ou X.P1PH1 Si cette fonction s'avère pratique, il faut rester prudent en particulier si on travailole avec plusieurs objets qui utilisent des noms de variables similaires.

attach('test001')

Histogramme

L'histogramme est un graphe qui représente la fréquence d'ocurrence absolue ou relative d'une variable divisée en classes d'amplitudes égales. Il nous renseigne de façon immédiate sur les caractéristiques de distribution de cette variable.

STATA

histogram p1ph1, bin(17) frequency

Stata appelle cet objet "Graph", nous pouvons ensuite en modifier les couleurs:

graph display Graph, margin(tiny) scheme(s1mono)

Image:Hist_p1ph1_stata1.png

on remarquera que par défaut STATA fait des histogrammes de densité au lieu d'histogrammes de fréquence:

histogram p1ph1, bin(17)
graph display Graph, margin(tiny) scheme(s1mono)

Image:Hist_p1ph1_stata2.png

ajoutons une distribution normale pour comparaison:

histogram p1ph1, bin(17) normal normopts(lpattern(dash) lcolor(red) lwidth(medthick))

Image:Hist_p1ph1_stata3.png

et additionnellement une courbe de densité de la distribution empirique:

histogram p1ph1, bin(17) normal normopts(lpattern(dash) lcolor(red) lwidth(medthick)) kdensity

Image:Hist_p1ph1_stata4.png

R

Nous utilisons la fonction hist(). Consultons le manuel:

start.help()
help(hist)

Nous souhaitons visualiser l'histogramme de la variable X.P1PH1 du tableau test001:

hist(test001$X.P1PH1, breaks=17, col="light blue")

nous obtenons un histogramme de fréquences:

Image:Hist_p1ph1_001.png

Nous pouvons aussi calculer un histogramme de probablilités. Observer le changement dans l'axe des ordonnées. L'aire totale de l'histogramme égale 1.

hist(test001$X.P1PH1, breaks=17, col="light blue", probability = TRUE)

Image:Hist_p1ph1_002.png

Il devient alors possible de comparer la distribution de notre variable à celle d'une loi normale. Nous devons pour cela calculer une distribution normale avec la même moyenne et déviation standard que nos données expérimentales:

f <- function(x) { 
                   dnorm(x,
                   mean=mean(test001$X.P1PH1),
                   sd=sd(test001$X.P1PH1),)
                  }

puis nous l'appliquons au graphique généré au préalable:

curve(f,add=T,col="red",lwd=3,lty=2)

avec le résultat suivant:

Image:Hist_p1ph1_003.png

Nous pouvons alors surimposer la fonction de densité des données d'observation:

lines(density(test001$X.P1PH1), col='red', lwd=3)

Image:Hist_p1ph1_004.png

Cette représentation a l'avantage d'être intuitive et didactique, mais la méthode de calcul décrite ici fonctionne mal lorsqu'il y a des données manquantes (essayez de reproduire le résultat avec la variable X.P1PH2 par exemple). L'interprétation laisse beaucoup à la subjectivité. Le recours aux diagrammes quantile-quantile est recommandé dans ce cas.

Diagramme quantile-quantile (q-q plot)

Dans la pratique, lorsqu'on veut représenter la comparaison d'une fonction de répartition empirique avec une distribution normale, on utilise le diagrame quantile-quantile ou "q-q plot": "diagramme représentant la fonction de répartition empirique, gradué selon les fractiles de la loi normale réduite". Plus la répartition empirique se rapproche de la répartition d'une loi normale, plus les points apparaissent alignés le long d'une droite appelée droite de Henry.

Malgré leur attrait, les méthodes graphiques ne nous fournissent pas de critères véritablement objectifs pour juger de la normalité d'une distribution de données expérimentales[1]. De ce fait, il est important de savoir mettre en oeuvre les tests de normalité chaque fois que la question se pose.

STATA

La fonction qnorm nous permet de comparer une distribution empirique à une distribution selon la loi normale:

qnorm p1ph1, rlopts(lcolor(red))
graph display Graph, margin(tiny) scheme(s1color)

Image:Qqplot_p1ph1_stata1.png

Le diagramme quantile-quantile est utile lorsqu'on cherche à répondre à des questions telles que:

  • est-ce que les échantillons proviennent de populations avec une distribution semblable?
  • est-ce que les échantillons ont des profils de distribution similaires?
  • est-ce que les variables périphériques ont un comportement similaire?

Comparons par exemple les distributions du premier et du deuxième hématocrites p1ph1 et p1ph2

qqplot p1ph1 p1ph2, rlopts(lcolor(red))
graph display Graph, margin(tiny) scheme(s1color)

Image:Qqplot_p1ph1_p1ph2_stata2.png

R

qqnorm(test001$X.P1PH1)
qqline(test001$X.P1PH1,col="red", lwd=3)

Image:Qqplot_p1ph1_001.png

Le diagramme quantile-quantile est utile lorsqu'on cherche à répondre à des questions telles que:

  • est-ce que les échantillons proviennent de populations avec une distribution semblable?
  • est-ce que les échantillons ont des profils de distribution similaires?
  • est-ce que les variables périphériques ont un comportement similaire?

Comparons par exemple les distributions du premier et du deuxième hématocrites X.P1PH1 et X.P1PH2. Nous utilisons pour cela la fonction qqplot(). La fonction plot.qqline() qui nous permet de dessiner la ligne de référence est fournie par l'extension sma:

qqplot(test001$X.P1PH2,test001$X.P1PH1)
plot.qqline(test001$X.P1PH2,test001$X.P1PH1,col="red",lwd=3)

Image:Qqplot_p1ph1_p1ph2_001.png

En l'ocurrence, les deux distributions sont légèrement différentes.

par(mfrow=c(2,1)) ; segmente en deux lignes le dispositif graphique
hist(test001$X.P1PH1, breaks=17, col="light blue", probability = TRUE,
xlim = c(20,50), main = "") hist(test001$X.P1PH2, breaks=17, col="light blue", probability = TRUE,
xlim = c(20,50), main = "") par(mfrow=c(1,1)) ; retourne le dispositif graphique à la configuration antérieure

Image:Hist_p1ph1_p1ph2_001.png

Nous devrons tester si cette différence est significative.

Mais surtout l'existence d'une tracé de densité bimodal associé à la non normalité des données doit nous faire suspecter un mélange de populations avec des caractéristiques différentes. Voici ce qu'on observe si on sépare les enfants de 1 à 6 ans (en noir) des enfants de 6 à 12 ans (en rouge):

(pour la méthode utilisée pour élaborer ce graphique voir ici)

"Stripcharts"

STATA

N/A

R

stripchart(test001$X.P1PH2,method="jitter",xlim=c(20,55))
stripchart(test001$X.P1PH1,method="jitter",xlim=c(20,55))

très moyennement utile dans ce cas:

Image:Strip_p1ph1_p1ph2_001.png

Graphe de fréquences cumulées

Ce type de graphe est parfois utilisé pour inspecter la distribution des données d'une variable, tout comme le graphe quantile-quantile.

STATA

cumul p1ph1, generate(cp1ph1)
line cp1ph1 p1ph1, sort

Image:Stata_cumul_p1ph1.png

R

Nous allons reprendre une fonction ad hoc de Vincent Zoonekynd pour générer un graphe de effectifs cumulés. Copier ce texte et le coller dans la libne de commandes de R:

cumulated.frequencies <- function (x, main="") {
  x.name <- deparse(substitute(x))
  n <- length(x)
  plot( 1:n ~ sort(x), 
        xlab = x.name, 
        ylab = 'Fréquences cumulées',
        main = main
      )
}

nous voulons le graphe de effectifs cumulés de la variable X.P1PH1:

cumulated.frequencies(X.P1PH1, main = "p1ph1")

Image:Freq_cumul_p1ph1.png

Corrélation et régression

STATA

distribution de p1ph2 par rapport à p1ph1 avec les deux droites de régression.

twoway (scatter p1ph2 p1ph1) (lfit p1ph2 p1ph1) (lfit p1ph1 p1ph2)

Image:Scatter_p1ph1_p1ph2_stata.png

examinons le coefficient de corrélation:

correlate p1ph1 p1ph2

résultat:

(obs=705)
             |    p1ph1    p1ph2
-------------+------------------
       p1ph1 |   1.0000
       p1ph2 |   0.9419   1.0000

autre possibilité, avec niveau de signifiance et décompte des observations appariées:

pwcorr p1ph1 p1ph2, sig obs

résultat:

             |    p1ph1    p1ph2
-------------+------------------
       p1ph1 |   1.0000 
             |
             |      754
             |
       p1ph2 |   0.9419   1.0000 
             |   0.0000
             |      705      705
             |

R

plot(test001$X.P1PH2 ~ test001$X.P1PH1)

et les deux droites de régression:

abline(lm(test001$X.P1PH2 ~ test001$X.P1PH1),col="red")
abline(lm(test001$X.P1PH1 ~ test001$X.P1PH2),col="blue")

Image:Scatter_p1ph1_p1ph2_001.png

Les deux séries d'observations sont hautement corrélées.

Vérifions le coefficient de corrélation:

cor(test001$X.P1PH1,test001$X.P1PH2, use="complete")
[1] 0.942

et avec le test de corrélation:

cor.test(test001$X.P1PH1,test001$X.P1PH2, alternative="two.sided",
method="pearson", conf.level= 0.98)

réponse:

        Pearson's product-moment correlation

data:  test001$X.P1PH1 and test001$X.P1PH2
t = 74.3, df = 703, p-value < 0.00000000000000022
alternative hypothesis: true correlation is not equal to 0
98 percent confidence interval:
 0.931 0.951
sample estimates:
  cor
  0.942

Diagramme de Tukey ("boxplot", "boîte à moustaches")

STATA

graph hbox p1ph2 p1ph1

Image:Boxplot_p1ph1_p1ph2_stata.png

R

boxplot(test001$X.P1PH1,test001$X.P1PH2, horizontal = TRUE, notch = TRUE,
col="light blue")

Image:Boxplot_p1ph1_p1ph2_001.png

Exercices

  • générez un histogramme, un diagramme de Tukey et un diagramme quantile-quantile pour la variable X.P1PTEMP (ou p1ptemp). Que remarquez-vous?


Références

R Graph galleries

Vincent Zoonekind: Statistics with R

Statistical graphics and experimental data Nikolic-Doric et coll. 2006

STATA Tutorial. Carolina Population Center

Stata topics: Graphics (UCLA)

Introduction to Stata Graphics with associated Stata code and output (U. Michigan)

Dartmouth Social Science Computing: Frequently asked questions on Stata

Lectures recommandées

Designing science graphs for data analysis and presentation. The bad, the good and the better. Kelly et coll. 2005

Park HM (2004) Testing normality in SAS, STATA, and SPSS

Bounessah M The boxplot: A robust exploratory data analysis tool for the definition of the threshold for outlier data.

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