olivier godechot

Faire un tableau croisé sur R



Si l'on regarde les options par défaut, les statistiques descriptives ne semblent pas être le point fort de R. Cela semble à première vue très minimal et peu pratique. Mais en fouillant bien, on se rend compte que l'on peut faire pas mal de choses et que certaines options peuvent s'avérer très pratiques. Voyons le cas à partir de quelques exemples.

Travaillons toujours à partir de l'article de François Héran sur la possession de chiens et de chats (cf. Manipuler les données avec R). Nous voulons créer un tableau permettant de connaître la proportion de ménage possédant un chat en fonction du sexe du chef de ménage.

#Importation des données

library("foreign")
heran<-read.xport("/media/win_d/R/heran.xpt")

# Avant toutes choses, un coup d'oeil à
# la distribution des variables

table(heran$CSEX)
table(heran$CHAT)

#OK. Pas de valeurs manquantes... Mais il faut
#recréer des variables peut-être un peu plus
#lisibles.

heran$a_chat=ifelse(heran$CHAT=="00","Pas de chat","A un chat")
heran$sexe_chef=ifelse(heran$CSEX=="1","Homme","Femme")

#Maintenant le tableau croisé

tableau<-table(heran$sexe_chef,heran$a_chat)
print(tableau)


Le tableau croisé qui en ressort est plutôt fruste.

        A un chat Pas de chat

Femme 218 1085
Homme 1095 3484


Pas de marge ! Pas de pourcentage (total, en ligne, en colonne). Bref, on regrette de prime abord la proc freq de SAS. Le fait que l'objet « tableau » que l'on vient de créer est une matrice ne rassurera pas forcément. Et pourtant ! C'est pratique. On peut faire sur cet objet toutes les manipulations matricielles : inversion, transposition, recherche des valeurs propres, etc.

Attribuer des marges n'est pas trop compliqué. On a la fonction addmargins.

addmargins(tableau)


        A un chat Pas de chat  Sum

Femme 218 1085 1303
Homme 1095 3484 4579
Sum 1313 4569 5882


Voilà qui est mieux. La fonction prop.table donne les pourcentages (globaux, en ligne ou en colonne).

#Pourcentage total
prop.table(tableau)

#Pourcentage en ligne
prop.table(tableau,1)

#Pourcentage en colonne
prop.table(tableau,2)


Ce qui donne pour les pourcentages en ligne, ceci.

        A un chat Pas de chat

Femme 0.1673062 0.8326938
Homme 0.2391352 0.7608648


16,7% des ménages dont le chef est une femme possède au moins un chat contre 23,9% des ménages dont le chef est un homme. A priori, ça colle avec les données de François Héran. Mais me diriez-vous... on a les pourcentages en ligne, mais pas les marges...

Voici ce qui améliore les choses.

#Pourcentage en ligne + marge
addmargins(prop.table(addmargins(tableau,1),1),2)


et donne ceci :

        A un chat Pas de chat       Sum

Femme 0.1673062 0.8326938 1.0000000
Homme 0.2391352 0.7608648 1.0000000
Sum 0.2232234 0.7767766 1.0000000


Mais l'effectif ? On ne peut pas reconstituer le tableau !
Voici un tableau comme je les aime : % en ligne, la colonne avec les 100% et l'effectif pour reconstituer le tableau.


tabligne=cbind(addmargins(prop.table(addmargins(tableau,1),1),2), c(margin.table(tableau,1),sum(tableau)))

colnames(tabligne)<-c(colnames(tableau),"TOTAL","EFFECTIF")

tabligne


Ce qui donne ceci :

      A un chat Pas de chat TOTAL EFFECTIF

Femme 0.1673062 0.8326938 1 1303
Homme 0.2391352 0.7608648 1 4579
Sum 0.2232234 0.7767766 1 5882


Explication des fonctions utilisées :
- cbind() fusionne des colonnes de matrices différentes.
- addmargins(tableau,1) ajoute une marge pour les colonnes.
- c() est une liste de valeurs
- sum() fait la somme
- colnames() attribue ou manipule des noms de colonne d'un objet.

Pour les pourcentage en colonne, voici la formule


tabcol=rbind(addmargins(prop.table(addmargins(tableau,2),2),1), c(margin.table(tableau,2),sum(tableau)))

rownames(tabcol)<-c(rownames(tableau),"TOTAL","EFFECTIF")

tabcol


Voilà il me reste plus qu'à trouver comment afficher des pourcentages en format de sortie et ce sera parfait.

LES COMMENTAIRES | COMMENTS

Ajouter un commentaire
Add a comment

Votre (Sur-)nom |Your (Nick-)name


Votre courriel |Your mail
(Il ne sera pas affiché |It will not be displayed))


Votre Commentaire | Your comment


Pour montrer que vous n'êtes pas un robot spammeur, merci de recopier l'image suivante en sens inverse
To show that you are not a spamming robot, please copy the content of the following image in reverse order
:

<< Retour au Commentaires

Français | English

Actualités   

OgO: plus ici|more here

Tweets (rarely/rarement): @OlivierGodechot

[Webmestre]

[Fil rss]

[V. 0.93]

HOP

Système d'aide à la publication sur Internet


000

clics / mois.