Chronique R – Caractères spéciaux dans les graphiques

le 17 avril 2013 à 10:03
dtalbot

Le logiciel R contient des fonctions relativement faciles d’utilisation pour créer toutes sortes de graphiques. Ces fonctions sont également très flexibles, puisqu’elles permettent de personnaliser plusieurs éléments des graphiques. Dans cette chronique, je ferai un bref survol de certaines fonctions de base qui permettent de créer des graphiques en R et je montrerai plus spécifiquement comment on peut insérer des caractères spéciaux dans le titre, les noms des axes, la légende d’un graphique, etc.

Pour illustrer ces notions, considérons l’exemple suivant : nous nous intéresserons à l’erreur de type 1 (la probabilité de rejeter l’hypothèse nulle lorsque celle-ci est vraie) dans une situation où nous voulons comparer la moyenne de deux échantillons. Nous supposerons que les échantillons proviennent tous les deux d’une distribution normale de moyenne nulle, mais que les variances diffèrent entre ces deux distributions. Nous allons comparer l’erreur de type 1 pour le test de Student classique, le test de Student avec correction de Satterthwaite pour les degrés de liberté et le test non-paramétrique de Mann-Whitney.

Nous simulerons 1000 répétitions de deux échantillons indépendants en faisant varier les tailles d’échantillon de chaque groupe de 2 à 500. À chaque répétition, nous vérifierons pour chacun des trois tests si la valeur p associée est inférieure au seuil de 0.05. Nous calculerons ensuite pour chaque taille d’échantillon, la proportion des simulations pour lesquelles l’hypothèse nulle a été rejetée à tort. Voici le code R proposé :

set.seed(1378193); #Germe de la simulation

type1 = matrix(0, nrow = 499, ncol = 3); #matrice qui contiendra les résultats

type1.temp = matrix(0, nrow = 1000, ncol = 3);

#matrice qui contiendra certains résultats temporaires

i = 1; #initialisation d’un indice

for(n in 2:500) #boucle pour différentes tailles d’échantillon

{

for(j in 1:1000) #boucle pour 1000 répétitions par taille d’échantillon

{

Y1 = rnorm(n, mean = 0, sd = 1); #simulation du premier échantillon

Y2 = rnorm(n, mean = 0, sd = 3); #simulation du second échantillon

type1.temp[j, 1] = t.test(Y1, Y2, var.equal = T)$p.value < 0.05;

#t-test en supposant des variances égales

type1.temp[j, 2] = t.test(Y1, Y2, var.equal = F)$p.value < 0.05;

#t-test en supposant des variances différentes (Satterthwaite)

type1.temp[j, 3] = wilcox.test(Y1, Y2)$p.value < 0.05;

#test non paramétrique de Mann-Whitney

}

type1[i,] = colMeans(type1.temp); #Erreur de type 1 pour une taille d’échantillon donnée

i = i + 1; #incrémentation de l’indice

}

Notons que cette façon de faire, bien qu’intuitive, n’est pas la plus efficace. Nous avons vu à la dernière chronique qu’en éliminant les boucles, on peut réduire le temps de calcul des programmes. Nous pourrions ici éliminer la boucle sur j à l’aide de tableaux array et de la fonction apply, mais le code serait un peu plus difficile à comprendre.

Afin de visualiser les résultats, nous pourrions créer un graphique comme celui-ci :

Pour créer ce graphique, il faut utiliser quelques fonctions graphiques. On y voit également quelques caractères spéciaux, dont la lettre grecque alpha oule zéro en indice dans H0.

D’abord, nous créerons un vecteur qui contiendra les différentes tailles d’échantillons testées :

n = 2:500;

Ensuite, nous pourrons créer le graphique avec la fonction plot, graphique auquel nous ajouterons divers éléments par la suite. La fonction plot contient différents arguments dont :

  • x - la variable contenant les coordonnées en abscisse des points;
  • y - la variable contenant les coordonnées en ordonnée des points;
  • type - qui indique le type de liaisons entre les points (par exemple « l » pour lignes);
  • xlab – le titre de l’axe des x;
  • ylab - le titre de l’axe des y;
  • main – le titre du graphique;
  • ylim – un vecteur à deux éléments contenant les limites inférieure et supérieure de l’axe des y;
  • xlim – un vecteur à deux éléments contenant les limites inférieure et supérieure de l’axe des x;
  • col – indique la couleur des points et des liaisons.

Dans notre graphique de base, nous pouvons voir que des caractères spéciaux apparaissent dans le titre de l’axe des y. Il faudra utiliser la fonction expression pour que R comprenne que nous voulons utiliser des expressions mathématiques dans le titre de cet axe. La façon dont nous allons procéder est de diviser le titre de l’axe des y en plusieurs sous-expressions. Certaines sous-expressions seront mathématiques, alors que d’autres seront du texte ordinaire.

À l’intérieur de la fonction expression, nous utiliserons la fonction paste pour joindre ensemble les différentes sous-expressions, que nous séparerons par des virgules. Afin d’identifier les sous-expressions qui sont du texte ordinaire, nous utiliserons la fonction plain.

Notons que les parenthèses ont un statut particulier : il faut les insérer seules dans une sous-expression et les entourer de guillemets ( » « ). Pour insérer des lettres grecques, nous écrirons simplement leur nom. Les termes à inscrire en indice sont insérés entre crochets ([ ]), alors que les termes à mettre en exposant sont inscrits après un accent circonflexe (^). Afin d’afficher un « = », on inscrit « == ». Dans le code suivant, nous créons un objet qui contient l’expression à utiliser pour l’axe des y.

ylab.name = expression(paste(P, »(« ,plain(« rejeter « ), H[0], plain( » | « ), H[0], plain(« vrai »), « ) », plain(« , avec « ), alpha == 0.05));

Afin de mieux comprendre, décortiquons une partie de ce code. D’abord, tel que mentionné, nous utilisons la fonction expression, puis à l’intérieur de cette fonction, nous utilisons la fonction paste. La première sous-expression est simplement un P. La deuxième sous-expression est une parenthèse, que nous avons isolée entre guillemets. La troisième sous-expression est « rejeter  » écrite avec du texte ordinaire, nous écrivons donc plain(« rejeter « ). La quatrième sous-expression est H0, que nous écrivons H[0], etc.

Avec tous ces éléments, nous sommes prêt à créer le graphique :

plot(n, type1[,1], type = « l »,

xlab = « n », ylab = ylab.name, ylim = c(0,0.1),

main = « Erreur de type 1 en fonction de n »);

Ce graphique ne contient toutefois que la partie pour le test de Student classique. Il suffit alors d’y ajouter les éléments pour le test de Student avec correction de Satterthwaite et le test de Mann-Whitney. Pour ce faire, nous utilisons la fonction lines, qui permet d’ajouter des lignes à un graphique déjà existant. Sa syntaxe est très similaire à celle de plot :

lines(n, type1[,2], type = « l », col = « blue »);

lines(n, type1[,3], type = « l », col = « green »);

Nous ajoutons une ligne horizontale à ce graphique avec la fonction abline. Nous n’utiliserons ici que les arguments h pour une ligne horizontale, lwd pour définir l’épaisseur du trait et col pour la couleur :

abline(h = 0.05, lwd = 2, col = « red »);

Finalement, nous utiliserons la fonction legend pour ajouter une légende au graphique. Ses principaux arguments sont :

  • x – L’absice du coin supérieur gauche de la légende;
  • y – L’ordonnée du coin supérieur gauche de la légende;
  • lty – Les différents types de lignes à représenter dans la légende;
  • col – Les différentes couleurs à représenter dans la légende;
  • legend - les textes pour identifier les différents éléments de la légende;
  • bty – « o » pour que la légende soit encadrée et « n » sinon.

Le code proposé est le suivant :

legend(x = 50, y = 0.03, lty = 1,

col = c(« black », « blue », « green », « red »),

legend = c(« t-test classique », « t-test avec correction »,

« Mann-Whitney », expression(alpha == 0.05)), bty = « n »);

Même si l’objectif principal de cette chronique était de montrer comment insérer des caractères spéciaux dans les graphiques et d’en profiter pour aborder certaines fonctions graphiques en R, notre simulation montre également des résultats intéressants! Il semblerait en effet que, selon nos résultats, le test de Student classique et celui avec correction sont à peu près équivalents, du moins dans notre exemple, quant à l’erreur de type 1, quelle que soit la taille d’échantillon. Pour ces deux tests, le seuil observé correspond bien au seuil nominal. Par contre, le test de Mann-Whitney a un seuil observé généralement un peu plus grand (autour de 0.07) que le seuil nominal. Cet exemple montre qu’il faut bien faire attention aux hypothèses des tests, mêmes quand ils sont dits «non-paramétriques»! En effet, le test de Mann-Whitney suppose que les distributions des deux échantillons à comparer sont quelconques, mais identiques, sauf en ce qui a trait à un paramètre de localisation. Puisque les variances des deux échantillons sont différentes, les hypothèses du test de Mann-Whitney ne sont pas vérifiées dans cet exemple.

Denis Talbot

Retour à la table des matières

FacebookTwitterGoogle+LinkedIn