• Medium

Free online content available in this course.

You can get support and mentoring from a private teacher via videoconference on this course.

Got it!

Last updated on 10/9/17

Manipuler et comparer plusieurs vecteurs

Log in or subscribe for free to enjoy all this course has to offer!

Grace aux chapitres précédents vous avez appris à manipuler les vecteurs de différentes manières et en extraire des informations statistiques. Nous allons maintenant passer à une étape supérieure en manipulant et comparant plusieurs vecteurs à la fois pour par exemple déterminer les valeurs qu'ils contiennent en commun, les ordonner de manière consistente ou encore les comparer des manièr statistique.

Pour rendre ce chapitre plus didactique nous allons y analyser un jeu de données correspondant à une petite expérience qui sera détaillée ci dessous. Au cours des différentes sections nous apprendrons à harmoniser les données entre les différents vecteurs et à les comparer statistiquement en découvrant les méthodes et fonctions adéquates. On peut donc voir cela comme un mini TP dirigé.

Imaginons une expérience

Pour le déroulement de ce chapitre nous allons travailler sur quatre vecteurs issus d'une expérience simulée, les résultats provenant de ces analyses pourraient donc ne pas refléter la réalité même si le jeu de données vise à rester réaliste. :)
Ces données proviennent d'une (supposée) expérience visant à déterminer si la taille d'un individu est liée à sa performance établie lors d'une épreuve de saut en hauteur et si il existe des différences entre filles et garçons tant du point de vue performance que de la potentielle liaison entre taille et performance. On mesure pour cela la taille de chacun de ces individus et on relève leur meilleure performance lors d'une série de 3 sauts en hauteur.

Pour travailler sur ces jeux de données vous pouvez télécharger le fichier de sauvegarde contenant les quatre vecteurs suivants:

  • tailleG: vecteur contenant la taille en centimètres de tous les individus de sexe masculin.

  • performanceG: vecteur contenant la meilleure de 3 performances (en centimètres) en saut en hauteur pour les individus de sexe masculin.

  • tailleF: vecteur contenant la taille en centimètres de tous les individus de sexe féminin.

  • performanceF: vecteur contenant la meilleure de 3 performances (en centimètres) en saut en hauteur pour les individus de sexe féminin.

Sauvegardez donc ce fichier dans le dossier donnees créé lors des chapitres précédents et importez-le grace à la fonctionload().

> # On définit le répertoire de travail
> setwd("/Users/votrelogin/R/")
>
> # On importe l'objet contenant les données
> objets <- load("donnees/Chapitre7.RData")
>
> # On affiche le nom des objets qui ont été importés
> objets

Les objets ont bien été importés. :)
A l'aide des chapitres précédents si besoin, vous pouvez d'ores et déjà jeter un premier coup d'oeil aux vecteurs importés et par exemple en déterminer la longueur, en afficher le contenu ou encore calculer les mesures statistiques (médiane, moyenne, variance,...) définissant les distributions numériques contenues dans ces vecteurs.

Opérations ensemblistes

Une des premières observations que vous avez peut être effectuée en jetant un premier regard sur ces données est que le nombre d'observations diffèrent. Par exemple, pour le groupe de sujets masculins nous avons 23 mesures de taille pour 24 mesures de performance tandis que le groupe de sujets féminins comporte 23 mesures de taille et 26 de performance.

> length(tailleF)
[1] 23
> length(performanceF)
[1] 26
> 
> length(tailleG)
[1] 23
> length(performanceG)
[1] 24
>

Une autre chose que vous avez certainement remarqué est que ces vecteurs sont indexés par des noms (mais aussi des index numériques comme tout vecteur). Pour rappel, les noms sont un attribut des objets de type vecteur. Vous pouvez donc récupérer cet attribut grace à la fonctionnames()qui vous renverra les noms du vecteur donné en argument sous la forme... d'un vecteur. Quand je vous dis que les vecteurs sont omniprésents en R j'espère que vous me croyez. ^^

> # Affichage des noms associés aux différentes mesures.
> names(tailleG)
 [1] "Vincent"   "Pierre"    "Karim"     "Michel"    "Eric"      "Kevin"     "Paul"      "Youssef"   "Alain"    
[10] "Ruy"       "Adrien"    "Bastien"   "Jacques"   "Christian" "Justin"    "Julien"    "Philippe"  "Benoit"   
[19] "Thimothee" "Francois"  "Diego"     "Jean"      "Fabien"   
> names(performanceG)
 [1] "Ruy"       "Eric"      "Bastien"   "Claude"    "Diego"     "Francois"  "Karim"     "Youssef"   "Vincent"  
[10] "Cedric"    "Thimothee" "Paul"      "Julien"    "Philippe"  "Matteo"    "Fabien"    "Adrien"    "Christian"
[19] "Jean"      "David"     "Jacques"   "Benoit"    "Pierre"    "Michel"   
> 
> names(tailleF)
 [1] "Katia"       "Mireille"    "Angelique"   "Emilie"      "Christine"   "Estelle"     "Jacqueline" 
 [8] "Magali"      "Ana"         "Cheryl"      "Lucie"       "Emmannuelle" "Marion"      "Chloe"      
[15] "Zoe"         "Fatima"      "Irene"       "Aurelia"     "Karen"       "Julie"       "Mathilde"   
[22] "Juliette"    "Chen"       
> names(performanceF)
 [1] "Marion"      "Karen"       "Christine"   "Sandrine"    "Cheryl"      "Fatima"      "Delphine"   
 [8] "Lucie"       "Aurelia"     "Irene"       "Mathilde"    "Emilie"      "Ana"         "Elsa"       
[15] "Chen"        "Estelle"     "Julie"       "Chloe"       "Liza"        "Josette"     "Emmannuelle"
[22] "Angelique"   "Juliette"    "Magali"      "Katia"       "Mireille"

La première étape de notre analyse va donc être de faire un petit peu le tri dans nos données. Nous ne pourrons effectivement travailler qu'avec les individus pour lesquels nous disposons à la fois de la taille et de la performance en saut en hauteur. Notre but est donc maintenant:

  • de savoir combien d'individus ont au total été inclus dans cette étude.

  • de savoir pour quels individus nous disposons à la fois des mesures de taille et de saut.

  • de savoir pour quels individus nous ne disposons que d'une seule de ces valeurs.

  • de générer de nouveaux vecteurs ne contenant que les données que nous pouvons analyser.

Pour arriver à nos fins nous allons avoir besoin de fonctions permettant de comparer plusieurs ensembles. Dans notre cas, les ensembles que nous souhaitons comparer sont les noms des individus pour lesquels nous disposons de mesures soit de taille, soit de performance. Par exemple, les noms des filles dont nous avons une mesure de taille est un ensemble, les noms de celles pour lesquelles nous avons une mesure de performance en est une autre. Ces ensembles peuvent être stockés sous la forme d'un vecteur grace à la fonctionnames()comme nous l'avons vu précédemment. Nous savons donc désormais tout ce qu'il nous faut pour travailler, il ne reste plus qu'à découvrir les fonctions nous permettant d'arriver à nos fins.

Quel est l'ensemble des noms présents dans l'étude ?

Pour chacun de nos groupes (sujets féminins et masculins) nous allons tout d'abord établir la liste de tous les noms recensés, c'est à dire les noms pour lesquels nous disposons à la fois de mesures de taille et de performance. Il faut pour cela faire ce que l'on appelle l'union de ces deux ensembles. Tout ceci est possible grace à la fonction...union(). Elle prend comme arguments deux vecteurs et retourne l'ensemble des éléments se trouvant dans au moins un de ces vecteurs comme illustré ci-dessous.

> union(names(tailleG), names(performanceG))
 [1] "Vincent"   "Pierre"    "Karim"     "Michel"    "Eric"      "Kevin"     "Paul"      "Youssef"  
 [9] "Alain"     "Ruy"       "Adrien"    "Bastien"   "Jacques"   "Christian" "Justin"    "Julien"   
[17] "Philippe"  "Benoit"    "Thimothee" "Francois"  "Diego"     "Jean"      "Fabien"    "Claude"   
[25] "Cedric"    "Matteo"    "David"    
> union(names(tailleF), names(performanceF))
 [1] "Katia"       "Mireille"    "Angelique"   "Emilie"      "Christine"   "Estelle"     "Jacqueline" 
 [8] "Magali"      "Ana"         "Cheryl"      "Lucie"       "Emmannuelle" "Marion"      "Chloe"      
[15] "Zoe"         "Fatima"      "Irene"       "Aurelia"     "Karen"       "Julie"       "Mathilde"   
[22] "Juliette"    "Chen"        "Sandrine"    "Delphine"    "Elsa"        "Liza"        "Josette
>
> # On calcule la longueur de ces vecteurs
> length(union(names(tailleG), names(performanceG)))
[1] 27
> length(union(names(tailleF), names(performanceF)))
[1] 28

La fonctionunion()nous a donc permis de lister les 27 prénoms masculins et 28 féminins pour lesquels nous disposons d'au moins une mesure.

Quels noms sont communs aux deux ensembles ?

Nous allons maintenant déterminer l'ensemble de noms pour lesquels nous avons des mesures à la fois de taille et de performance. Il faut donc définir l'intersection des noms associés à ces deux mesures. Cela est possible grace à la fonctionintersect().
Cette fonction prend deux vecteurs en entrée et renvoie un nouveau vecteur contenant, de manière unique, les éléments présents dans chacun des deux vecteurs. Le code ci dessous permet de définir les prénoms masculins et féminins pour lesquels nous avons des mesures à la fois de taille et de performance. Les vecteurs de sortie sont respectivement stockés dans une variable pour pouvoir les réutiliser par la suite.

>communG <- intersect(names(tailleG), names(performanceG))
>communF <- intersect(names(tailleF), names(performanceF))
>
> length(communG)
[1] 20
> length(communF)
[1] 21

Les vecteurs communG et communF contiennent respectivement les 20 noms masculins et les 21 noms féminins pour lesquels nous avons un ensemble complet de données pour travailler.

Quels noms ne sont présents que dans un seul ensemble ?

Pour finir nous allons voir comment il est possible d'isoler les noms qui ne sont présents que dans un seul ensemble, c'est à dire la différence entre deux ensembles. En R, cette différence entre différents ensembles peut être définie grace à la fonctionsetdiff(x, y). Cette fonction prend deux vecteurs x et y en argument et renvoie les éléments de x qui ne sont pas dans y.

Cette portion de code permet donc de définir les noms pour lesquels nous n'avons qu'un seul type de mesure.

> # Noms présents dans les index de tailleG mais pas performanceG
> setdiff(names(tailleG), names(performanceG))
[1] "Kevin"  "Alain"  "Justin"
> # Et l'inverse!
> setdiff(names(performanceG), names(tailleG))
[1] "Claude" "Cedric" "Matteo" "David" 
> 
> setdiff(names(tailleF), names(performanceF))
[1] "Jacqueline" "Zoe"       
> setdiff(names(performanceF), names(tailleF))
[1] "Sandrine" "Delphine" "Elsa"     "Liza"     "Josette"

Grace à ces trois fonctions vous savez maintenant comparer le contenu de deux vecteurs et en définir l'union, l'intersection et les différences. La connaissance de ces fonctions vous sera très utile lorsque vous devrez découvrir ou organiser vos données. Il existe cependant une méthode alternative qui vous rendra elle aussi bien des services et utilise des booléens comme nous allons le découvrir.

L'opérateur %in%

Cette méthode utilise un opérateur du langage R qui vous est encore inconnu: %in%.
Cet opérateur s'utilise de la façon suivante:x %in yet renverra dans ce cas un vecteur d'éléments logiques (booléens) de la même taille que le vecteur x. Pour chaque élément de x l'opération renverra:

  • TRUE si cet élément se trouve aussi dans le vecteur y

  • FALSE dans le cas contraire

L'exemple ci-dessous montre ce qui se passe si l'on compare les vecteurs tailleG et performanceG.

> names(tailleG) %in% names(performanceG)
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
[17]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Le retour de cette opération nous indique que, par exemple, l'élément d'index 1 du vecteur tailleG est présent dans le vecteur performanceG mais pas les éléments d'indices 6, 9 et 15. Cette information brute est peu commode à lire je vous l'accorde mais peut être très utile si vous vous souvenez que les vecteurs peuvent être indexés grace à des booléens, en ne retenant que les éléments d'index de valeur TRUE. Ainsi, si vous souhaitez créer un vecteur contenant les éléments de tailleG associés à un nom aussi présent dans le vecteur performanceG il vous suffira d'utiliser un code comme celui exposé ci dessous.

> tailleG[names(tailleG) %in% names(performanceG)]
  Vincent    Pierre     Karim    Michel      Eric      Paul   Youssef       Ruy    Adrien   Bastien 
      169       175       182       166       179       165       168       179       167       172 
  Jacques Christian    Julien  Philippe    Benoit Thimothee  Francois     Diego      Jean    Fabien 
      156       191       183       178       175       190       172       173       185       171

Ainsi, le vecteur tailleG sera indexé selon le vecteur d'éléments logiques généré grace à l'opérateur%in%.

Ordonner les vecteurs de manière réciproque

Pour pouvoir continuer nos analyses nous allons maintenant devoir créer de nouveaux vecteurs contenant seulement les sujets pour lesquels nous avons toutes les données nécessaires. Grace à la section précédente vous avez déjà des éléments de réponse quant aux fonctions à utiliser. Cependant, il y a un aspect important à prendre en compte avant de commencer: la réciprocité des données.
Parmi les fonctions que nous allons devoir utiliser par la suite, certaines supposent que les différents vecteurs donnés en argument sont ordonnés de manière réciproque, c'est à dire que le premier élément du premier vecteur est associé au premier élément du second vecteur.
En regardant les données dont nous disposons vous pouvez vous rendre compte que l'ordre des noms n'est pas du tout le même entre les vecteurs taille et performance. Lorsque nous allons créer nos nouveaux vecteurs il faudra donc prendre cet élément en compte.

Précédemment nous avons vu deux méthodes permettant de définir les noms des sujets pour lesquelles nous possédions les mesures de taille et de performance au saut en hauteur: une utilisant la fonctionintersect()et l'autre l'opérateur%in%.
Dans notre cas il sera plus rapide t'utiliser la première méthode. En effet, l'opérateur %in% se contente de dire si un nom est présent dans les deux ensembles. Il ne changera pas l'ordre du vecteur; or nous avons vu qu'ils ne sont pas ordonnés de la même manière. Les vecteurs générés grace à la fonctionintersect()seront quant à eux plus utiles. En effet, ces vecteurs recensent la liste de noms pour lesquels nous avons les informations nécessaires pour les analyses. En indexant les nouveaux vecteurs créés grace à ces vecteurs, les vecteurs créés seront ordonnés de la même manière, suivant l'ordre de l'index transmis.
C'est exactement ce que fait le code ci dessous.

> # On créé deux nouveaux vecteurs en utilisant le même vecteur de noms afin d'avoir une réprocité des données entre les deux vecteurs
> tailleG2 <- tailleG[communG]
> performanceG2 <- performanceG[communG]
> 
> # Même chose pour les sujets féminins
> tailleF2 <- tailleF[communF]
> performanceF2 <- performanceF[communF]
>
> tailleG2
  Vincent    Pierre     Karim    Michel      Eric      Paul   Youssef       Ruy    Adrien   Bastien 
      169       175       182       166       179       165       168       179       167       172 
  Jacques Christian    Julien  Philippe    Benoit Thimothee  Francois     Diego      Jean    Fabien 
      156       191       183       178       175       190       172       173       185       171 
> performanceG2
  Vincent    Pierre     Karim    Michel      Eric      Paul   Youssef       Ruy    Adrien   Bastien 
      139       155       130       125       135       149       160       142       155       155 
  Jacques Christian    Julien  Philippe    Benoit Thimothee  Francois     Diego      Jean    Fabien 
      133       168       138       154       144       145       139       138       142       145 
>

Comme vous vous en rendez compte, le fait d'avoir créé les nouveaux vecteurs (stockés dans des nouvelles variables pour ne pas perdre les anciennes données) en utilisant un même index permet d'avoir de nouveaux vecteurs ordonnés de la même manière.

Le cas du tri

Le même problème revient lorsque l'on doit trier un des deux vecteurs. En en triant un, son ordre sera modifié et la réprocité avec le second vecteur sera perdue. Comme vu dans le chapitre précédent, il faut alors préférer la fonctionorder()à la fonctionsort(). La fonctionorder()renverra effectivement, non pas les valeurs triées des éléments du vecteur, mais leurs index. Cette fonction génèrera alors un vecteur contenant des index qui pourra être utilisé pour trier les deux vecteurs.
Pour notre analyse on souhaite maintenant trier les vecteurs tailleG2 et tailleF2 par ordre de taille croissant tout en conservant la réciprocité avec leurs vecteurs associés performanceG2 et performanceF2. Si vous avez bien compris que pour créer des vecteurs ordonnés de la même façon il suffit de les indexer avec un même vecteur d'index alors vous serez capables d'écrire le code permettant une telle manipulation. En cas de doute, la réponse se trouve ci-dessous.

 

tailleG2_tri <- tailleG2[order(tailleG2)]
performanceG2_tri <- performanceG2[order(tailleG2)]
 
tailleF2_tri <- tailleF2[order(tailleF2)]
performanceF2_tri <- performanceF2[order(tailleF2)]

Corrélations et régression linéaire

Maintenant que nos différents vecteurs ont été réorganisés il est temps de les utiliser pour faire des vraies statistiques! Nous allons commencer par étudier si il existe une corrélation entre la taille des sujets et leur performance en saut en hauteur.

Calcul de coefficient de corrélation linéaire

Calculer la corrélation entre deux variables revient à calculer l'intensité de leur liaison. Le coefficient de corrélation linéaire calculé est compris entre -1 et 1 et indique la force de cette liaison. Plus ce coefficient est proche d'une de ses valeurs extrêmes, plus la corrélation est forte. A l'inverse, un coefficient de corrélation de 0 indique qu'il n'y a pas de laison linéaire entre les données qui sont donc linéairement indépendantes. Il reste cependant possible que ces données soient corrélées de manière non linéaire.
Une corrélation positive (coefficient compris entre 0 et 1) indique que les deux séries de données évoluent dans le même sens (si les valeurs de la première série augmentent, les valeurs de la seconde série tendent à en faire de même). A l'opposé, une corrélation négative (coefficient compris entre -1 et 0) indique que les deux séries de données évoluent dans le sens opposé, lorsque les valeurs de l'une tendent à augmenter, les valeurs de l'autre tendent à diminuer.

Après cette partie théorique, passons à la pratique. Il est extrêmement simple de calculer un coefficient de corrélation linéaire avec R, il suffit de fournir les deux vecteurs à comparer comme argument à la fonctioncor(x,y). Il y a cependant deux précautions à prendre:

  • les deux vecteurs doivent être de même longueur et contenir des éléments numériques.

  • les données doivent être réciproques. Le premier élément du premier vecteur doit correspondre au premier élément du second vecteur et ainsi de suite. C'est exactement ce que l'on a appris à faire précédemment.

Nos deux couples de vecteurs tailleG2_tri, performanceG2_tri et tailleF2, performanceF2 remplissent ces conditions, on peut donc lancer les calculs de corrélations.

> cor(tailleG2_tri, performanceG2_tri)
[1] 0.2066602
> cor(tailleF2, performanceF2)
[1] 0.303197

Vous voyez, c'est très simple. Dans les deux cas nous avons donc une corrélation positive entre la taille et la performance au saut en hauteur. Cependant, cette corrélation reste faible (plus proche de 0 que de 1).

Régression linéaire

Souvenez vous, lorsque l'on calcule un coefficient de corrélation linéaire on recherche une relation linéaire entre nos deux jeux de données. C'est une chose importante à prendre en compte car parfois, le coefficient de corrélation obtenu sera égal à zéro mais cela ne signifiera pas pour autant qu'il n'existe pas de laison entre vos variables, seulement qu'il n'y a pas de corrélation linéaire. Les deux graphiques ci-dessous l'illustrent très bien.

Image utilisateur

Pour le graphique de gauche, il est facile de voir que nos deux jeux de données sont liés linéairement, ce qui est confirmé par un coefficient de corrélation linéaire de 1 (qui est la valeur maximale pour un coefficient de corrélation si vous avez suivi). Par contre, pour le graphique de droite, on peut voir qu'il existe une liaison entre nos deux variables mais que cette liaison n'est pas linéaire comme l'indique le coefficient de corrélation de 0. Ceux qui ont un niveau nécessaire en mathématiques auront certainement deviné que ces variables suivent plutôt une relation de type polynomiale mais ce n'est pas le plus important pour le moment.

Calculer une régression linéaire revient à déterminier la relation affine qui lie les deux variables. Si vous vous souvenez de vos cours de mathématiques vous vous rappelez alors qu'une fonction affine est une une fonction de la sorte $$y = ax + b$$ qui définit une droite. Les lettres y et x représentant les variables que l'on étudie, la lettre a la pente de la droite et la valeur b l'intersection de cette droite avec l'axe des ordonnées.
Pour résumer, calculer une régression linéaire revient à résoudre l'équation $$y = ax + b$$ de manière à ce que la droite définie par les paramètres a et b calculés lie au mieux les données.

Pour ceux qui préfèrent des images aux longs discours voici ce que cela donne de manière graphique en utilisant nos données de taille et de performance pour les garçons et les filles.

Image utilisateur

Sur ces graphiques chaque point représente un individu qui est placé selon sa taille (en abscisse) et sa performance (en ordonnées) en saut en hauteur. La droite en rouge correspond à la régression linéaire calculée pour chacun des couples de variables. La droite tend donc à passer au plus proche de tous les points et, les corrélations calculées auparavant étant positives, on remarque que la pente de la droite est elle aussi positive (la droite "monte"). Enfin, on avait observé que le coefficient de corrélation était plus élevé pour le groupe des filles que celui des garçons. Cette information se retrouve aussi ici dans la mesure où la pente de la régression linéaire semble plus forte pour les filles que pour les garçons.

Maintenant que les régressions linéaires n'ont (presque...) plus de secrets pour vous, voyons comment les calculer. Rassurez vous, c'est assez simple, il suffit de faire appel à une seule fonction qui se chargera de calculer les deux éléments nécessaires pour définir notre droite: les nombres a et b. Il s'agit de la fonctionlm()qui est l'abréviation de linear model qui signifie modèle linéaire en anglais.
Cette fonction a une syntaxe un peu particulière car elle prend une formule comme premier argument. Une formule consiste à indiquer que l'on souhaite étudier le comportement d'une variable en fonction d'une autre. Dans notre cas, on veut résoudre l'équation $$y = ax + b$$ et donc étudier le comportement de y en fonction de x.
La syntaxe est alorsy ~ x.
On peut donc utiliser cette syntaxe pour calculer la régression linéaire pour nos différents couples de variables, en étudiant le comportement de la performance d'un individu en saut en hauteur en fonction de sa taille.

> lm(performanceG2 ~ tailleG2)

Call:
lm(formula = performanceG2 ~ tailleG2)

Coefficients:
(Intercept)     tailleG2  
   100.2049       0.2537  

> lm(performanceF2 ~ tailleF2)

Call:
lm(formula = performanceF2 ~ tailleF2)

Coefficients:
(Intercept)     tailleF2  
    45.0287       0.4194

Le retour de ses fonctions peut sembler barbare mais il est au final assez simple à comprendre. Tout d'abord, la première ligne rappelle la formule utilisée.

Citation : Fonction lm

Call:
lm(formula = performanceF2 ~ tailleF2)

Ensuite, viennent les valeurs des nombres a et b que l'on souhaitait calculer, stockées de la manière suivante.

Citation : Fonction lm

Coefficients:
(Intercept) tailleF2
45.0287 0.4194

Le premier des deux nombres (Intercept) correspond à la valeur pour laquelle x=0, c'est à dire le nombre b, ou encore l'intersection de la droite avec l'axe des ordonnées.
Le second nombre, noté du nom de la variable x, correspond à la pente de de notre droite, c'est à dire le nombre a.
Comme le graphique précédent en donne l'impression, on voit ici, qu'effectivement, la pente de la droite de régression linéaire est plus élevée pour le groupe des filles que celui des garçons.

Effectuer des tests statistiques

Lorsque l'on compare des données en statistiques il est assez fréquent de noter des différences entre différents groupes d'observation. Nous avons par exemple observé précédemment une corrélation positive entre la taille d'un individu et sa performance en saut en hauteur. Mais nous avons aussi vu que cette corrélation était au final assez faible.
Le problème est donc qu'au bout d'un moment il faut trancher et donner une réponse claire et précise à votre chef ou professeur lorsqu'il vous pose des questions du genre: la corrélation entre taille et performance en saut est-elle positive? Les garçons sautent-ils plus haut que les filles?

C'est là qu'entrent en jeu les tests statistiques.
Il existe une multitude de ces tests pour, par exemple, comparer des médianes, des moyennes, des variances,... et le plus dur reste souvent de savoir lequel utiliser. Ces tests ont cependant tous un point commun, ils ont pour but d'infirmer ou confirmer une hypothèse de départ que l'on appelle l'hypothèse nulle (aussi notée H0). Cette hypothèse nulle consiste généralement à postuler une égalité entre les variables que l'on compare. Le test statistique permettra donc de confirmer ou d'infirmer cette hypothèse, c'est à dire de dire si elle est oui ou non vraie.

Donc le test statistique va répondre par oui ou non?

Pas exactement, le test statistique vous renverra ce que l'on appelle une p-value (prononcez pivalioue ^^ - parfois traduit en français par valeur p). Cette p-value est la probabilité (donc un nombre compris entre 0 et 1) que la différence observée entre nos deux observations soit due au hasard.
Il faut alors fixer un seuil pour lequel on pense être suffisamment sûr que la différence observée n'est pas du au hasard. Généralement on établit ce seuil à 5% (soit 0.05) ce qui signifie que la différence entre nos deux séries de données n'a que 5% de chances d'être due au hasard. Si la p-value est comprise entre 0 et 0.05 on dit que l'on rejete l'hypothèse nulle, l'hypothèse postulant une égalité entre les variables. On dit aussi que l'on accepte l'hypothèse alternative (qui est le contraire de l'hypothèse nulle et postule une différence entre les variables). On dit alors que la différence entre les deux variables est significative. Retenez bien ce terme, il est important.
Au contraire, si la p-value est supérieure au seuil fixé, on dit que l'on accepte l'hypothèse nulle et donc que l'on observe pas de différences significatives entre les variables considérées.

Voilà pour la théorie, passons maintenant à quelques exemples pratiques et nous allons essayer de répondre à ces deux questions concernant le jeu de données que nous avons analysé tout au long de ce chapitre:

  • peut-on dire que la corrélation entre taille et performance en saut en hauteur est positive ?

  • les garçons sautent-ils plus haut que les filles ?

Pour chacune de ses questions, nous allons donc utiliser des tests statistiques appropriés, les effectuer avec R et analyser les résultats renvoyés. Une fois nos données bien préparées, il n'est pas difficile d'effectuer ces tests qui ne nécessitent généralement que l'appel à une seule fonction. Le plus dur reste de savoir quel test effectuer et quelle fonction effectue ce test sous R.
Dans ce cas je vais vous présenter trois tests différents à titre d'exemple et nous utiliserons un seuil de rejet de l'hypothèse nulle de 5%.

Test de corrélation

Ce premier test, permet, pour le calcul d'un coefficient de corrélation, de tester l'hypothèse nulle H0: "Le coefficient de corrélation est égal à 0".
La fonction à utiliser s'appellecor.test(). Utilisons donc là avec notre jeu de données!

> cor.test(performanceG2, tailleG2)

        Pearson's product-moment correlation

data:  performanceG2 and tailleG2 
t = 0.8961, df = 18, p-value = 0.382
alternative hypothesis: true correlation is not equal to 0 
95 percent confidence interval:
 -0.2596016  0.5947868 
sample estimates:
      cor 
0.2066602 

> cor.test(performanceF2, tailleF2)

        Pearson's product-moment correlation

data:  performanceF2 and tailleF2 
t = 1.3869, df = 19, p-value = 0.1815
alternative hypothesis: true correlation is not equal to 0 
95 percent confidence interval:
 -0.14784  0.64983 
sample estimates:
     cor 
0.303197

Il faut donc maintenant interpréter ces résultats. Le plus simple (mais peut être pas le plus logique) et de les lire depuis la fin jusqu'au début. Tout d'abord la fonction rappelle le coefficient de corrélation (cor) qui, si vous souhaitez le vérifier, est bien le même que tout à l'heure. Rassurant. ^^
Ensuite la ligne "95 percent confidence interval:" indique l'intervalle de confiance de ce coefficient de corrélation pour un seuil donné (ici 95%). Les valeurs inférieures et supérieures sont renvoyées et signifie, dans l'exemple des données féminines, que le coefficient de corrélation est de 0.303197 mais que cette mesure a une "marge d'erreur" comprise entre -0.14784 et 0.64983. Cela nous indique que ce coefficient de corrélation pourrait tout aussi bien être négatif !
Montons maintenant de quelques lignes et attardons nous sur la valeur qui nous est donnée pour la p-value. Elle est de 0.1815 pour les filles et de 0.382 pour les garçons. Dans les deux cas cette p-value est donc (largement) supérieure à 0.05 ce qui signifie que l'on accepte l'hypothèse nulle postulant que le coefficient de corrélation est égal à 0. En effet, dans les deux cas, nous avons respectivement 38 et 18% de chances que ces coefficients de corrélation soit différents de 0 par hasard, ce qui donne donc une place trop importante au hasard !
Nous pouvons donc conclure que, autant pour les filles que pour les garçons, on observe une légère corrélation positive entre taille et performance en saut en hauteur mais que cette corrélation n'est pas signicativement différente de 0.

Test de médianes

Nous voulons maintenant répondre à notre deuxième question, à savoir si il existe une différence significative entre les performances en saut en hauteur des filles et des garçons. On peut par exemple comparer la hauteur moyenne ou médiane sautée par les deux groupes. Comme nous l'avons vu dans le chapitre précédent, la médiane est une mesure qui est moins affectée par d'éventuelles valeurs abbérantes et nous allons donc la préférer à la moyenne. Regardons donc d'abord les hauteurs médianes sautées par les deux groupes étudiées.

> median(performanceG2)
[1] 143
> median(performanceF2)
[1] 110

On s'aperçoit donc que les garçons sautent, de manière générale, 33 centimètres plus haut que les filles. La question est donc: cette différence est elle significative ?
Pour y répondre il nous faut donc appliquer un test destiné à comparer la médiane de deux séries de données. C'est ce que fait le test de Wilcoxon-Mann-Whitney dont l'hypothèse nulle postule une égalité des médianes des deux distribution. Ce test peut s'effectuer grace à la fonctionwilcox.test()qui prend comme arguments les deux vecteurs contenant les deux séries d'observations dont on veut comparer les médianes.

> wilcox.test(performanceF2, performanceG2)

        Wilcoxon rank sum test with continuity correction

data:  performanceF2 and performanceG2 
W = 6, p-value = 1.084e-07
alternative hypothesis: true location shift is not equal to 0

Le résultat est ici plus succint que précédemment et l'on peut donc se concentrer sur la lecture de la p-value qui est égale à 1.084e-07 soit 0.0000001084 en écriture sientifique.
Cette valeur est bien inférieure à notre seuil de 0.05 ce qui nous permet donc de rejeter l'hypothèse nulle. Le résultat de ce test nous apprend donc qu'il existe une différence significative de performances en saut en hauteur entre les groupes de garçons et de filles étudiés.

Il existe évidemment bien d'autres tests statistiques qui vous permettront de répondre à certaines questions. Le but de ce chapitre est simplement de présenter la démarche générale d'un test d'hypothèse à travers ces deux exemples. Une annexe verra le jour sous peu pour recenser les tests les plus communs afin de facilement trouver le nom de la fonction adéquate pour les effectuer en R.

Voilà qui en est fini pour ce chapitre très conséquent dans lequel nous nous serons concentrés d'abord sur des aspects de code puis, par la suite, sur des notions statistiques de base et la manière de les traiter sous R.

La suite de ce cours va maintenant aborder d'autres structures de données disponibles en R ainsi que la manière de les traiter. Nous laisserons donc un peu l'aspect statistique de coté pour quelques chapitres, j'espère que vous en avez bien profité ! :)

Example of certificate of achievement
Example of certificate of achievement