IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

R Discussion :

Tableaux croisés dynamiques avec R


Sujet :

R

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    554
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 554
    Par défaut Tableaux croisés dynamiques avec R
    Bonjour,

    j'ai une base de données contenant un nombre de personnes par catégorie professionnelle et sexe, pour un ensemble de départements et de communes.
    Ma base de données est un data.frame qui se présente comme ceci :
    DEP COM CSP SEXE NOMBRE
    Il peut y avoir des valeurs manquantes pour certains croisements de CSP x SEXE.

    Je voudrais réaliser le tableau simple suivant qui est simplement le résumé du nombre de CSP par département et sexe, un peu comme les tableaux croisés dynamiques dans EXCEL qui permettent d'obtenir immédiatement le même résultat ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
           |  Agriculteurs |    Ouvriers   |     Autres    |     Total     |
    -------+---------------+---------------+---------------+---------------+
       DEP |     SEXE      |     SEXE      |     SEXE      |     SEXE      |
           | H | F | Total | H | F | Total | H | F | Total | H | F | Total |
    -------+---+---+-------+---+---+-------+---+---+-------+---+---+-------+
        XX |   |   |       |   |   |       |   |   |       |   |   |       |
        YY |   |   |       |   |   |       |   |   |       |   |   |       |
        ZZ |   |   |       |   |   |       |   |   |       |   |   |       |
    -------+---+---+-------+---+---+-------+---+---+-------+---+---+-------+
     Total |   |   |       |   |   |       |   |   |       |   |   |       |
    Y-a-t'il une instruction R simple qui effectue ce type de travail ?

  2. #2
    Membre expérimenté
    Homme Profil pro
    Bioinformaticien
    Inscrit en
    Octobre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Bioinformaticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 126
    Par défaut
    Bonjour,

    Deux propositions : les paquets reshape2 et dplyr. Mention spéciale pour data.table si votre base de données est très volumineuse (à partir de 100 000 entrées).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # Comme il n'y a pas d'exemple concret de données, faire avec les moyens du bord.
    fusce <- read.table(header = TRUE, quote = "", stringsAsFactors = FALSE, text =
    "NUMSECU DEP COM CSP SEXE    NOMBRE
    pellentesque    Lorem   ipsum   dolor   sit 9853
    sagittis    amet    consectetuer    adipiscing  Nam    32
    fringilla   placerat   Ut   vestibulum   sit 14
    nulla   dictum   ipsum   dolor   elit 8710
    quisque vitae    felis    adipiscing  mauris    436
    egestas Lorem   purus   vestibulum   elit 3287
    eget    amet    consectetuer    adipiscing  Nam    1320
    auctor  vitae    Curabitur    gravida  arcu    1320")
    1) reshape2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    library("reshape2")
     
    proin <- melt(fusce, id.vars = "NUMSECU")
    orci <- acast(proin, variable ~ value)
     
    depVScom <- aperm(orci[c("DEP", "COM"),])
    cspVSsexe <- aperm(orci[c("CSP", "SEXE"), ])
    2) dplyr
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    library("dplyr")
     
    etiam <- tbl_df(fusce)
     
    odio <- group_by(etiam, DEP, COM) %>% arrange(CSP, SEXE)
    summarise(odio, totaux = sum(NOMBRE))
    Il y a donc une partie analytique qui génère, soit des données tabulaires potentiellement multivariées (au-delà de deux dimensions), soit des data.frames ou/et lists, un data.frame étant un cas particulier de list. Les lists justement peuvent contenir le rendu final qui sera sauvegardé/imprimé/etc. comme vous l'avez indiqué. D'autres outils sont capables de générer le rendu, tout dépend du format à utiliser.

  3. #3
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    554
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 554
    Par défaut
    Merci pour vos réponses, mais je dois dire que j'ai du mal à les utiliser.
    Voici un petit exemple avec une petite base de donnée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dep=c('01','01','01','01','01','01','02','02','02','02','02','02')
    Com=c('001','001','001','001','002','002','001','001','001','001','003','003')
    CSP=c('1','2','3','4','1','3','2','2','3','4','1','2')
    Sexe=c('1','1','1','2','1','1','1','2','1','2','1','1')
    Nombre=c(2,3,4,1,2,3,2,3,4,1,2,1)
    DF=data.frame(Dep,Com,CSP,Sexe,Nombre)
    Ça donne le tableau de données suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    DEP COM CSP SEXE NOMBRE
    01 001 1 1 2
    01 001 2 1 3
    01 001 3 1 4
    01 001 4 2 1
    01 002 1 1 2
    01 002 3 1 3
    02 001 2 1 2
    02 001 2 2 3
    02 001 3 1 4
    02 001 4 2 1
    02 003 1 1 2
    02 003 2 1 1
    Au final, je voudrais donc obtenir quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
           |       1      |       2      |       3      |       4      |    Total     |
    -------+--------------+--------------+--------------+--------------+--------------+
       DEP |     SEXE     |     SEXE     |     SEXE     |     SEXE     |     SEXE     |
           |  H |  F |  T |  H |  F |  T |  H |  F |  T |  H |  F |  T |  H |  F |  T |
    -------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
        01 |  4 |  0 |  4 |   3|   0|  3 |  7 |  0 |  7 |  0 |  1 |  1 | 14 |  1 | 15 |
        02 |  2 |  0 |  2 |   3|   3|  6 |  4 |  0 |  4 |  0 |  1 |  1 |  9 |  4 | 13 |
    -------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
     Total |  6 |  0 |  6 |   6|   3|  9 | 11 |  0 | 11 |  0 |  2 |  2 | 23 |  5 | 28 |
    Auriez-vous l'amabilité de m'écrire le code précis ?

  4. #4
    Membre expérimenté
    Homme Profil pro
    Bioinformaticien
    Inscrit en
    Octobre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Bioinformaticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 126
    Par défaut
    Bonjour
    À partir de ces données, voici un aperçu de ce dont reshape2 est capable car, pour un traitement pareil, dplyr serait too much.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    library("reshape2")
     
    # J'ai attribué des IDs aux entrées.
    xxx <- read.table(header = TRUE, quote = "", stringsAsFactors = FALSE, text =
    "ID DEP COM CSP SEXE NOMBRE
    A 01 001 1 1 2
    B 01 001 2 1 3
    C 01 001 3 1 4
    D 01 001 4 2 1
    E 01 002 1 1 2
    F 01 002 3 1 3
    G 02 001 2 1 2
    H 02 001 2 2 3
    I 02 001 3 1 4
    J 02 001 4 2 1
    K 02 003 1 1 2
    L 02 003 2 1 1")
     
    res1 <- acast(xxx, DEP ~ CSP + COM, sum)
    res2 <- acast(xxx, DEP ~ CSP + SEXE, sum)
    1) DEP vs CSP& COM
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cat("CSP :\t", levels(factor(xxx$CSP)), "\nCOM :\t", levels(factor(xxx$COM)), "\n")
    addmargins(res1)
    > ...
    CSP :	 1 2 3 4 
    COM :	 1 2 3
    > ...
        1_1 1_2 1_3 2_1 2_3 3_1 3_2 4_1 Sum
    1     2   2   0   3   0   4   3   1  15
    2     0   0   2   5   1   4   0   1  13
    Sum   2   2   2   8   1   8   3   2  28
    Interprétation. 1ère (rsp. 2ème) ligne = département « 1 » (rsp. « 2 »). Colonne « 1_1 » : dans la catégorie socio-professionnelle « 1 », il y a, pour la commune « 1 », 2 observations appartenant au premier département tandis que le deuxième n'est pas representé pour ces critères. De même avec le reste des colonnes. Les valeurs marginales dénombrent les observations relevées pour chaque ligne/colonne.

    2) DEP vs CSP & SEXE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cat("CSP :\t", levels(factor(xxx$CSP)), "\nSEXE :\t", levels(factor(xxx$SEXE)), "\n")
    addmargins(res2)
    > ...
    CSP :	 1 2 3 4 
    SEXE :	 1 2
    > ...
        1_1 2_1 2_2 3_1 4_2 Sum
    1     4   3   0   7   1  15
    2     2   3   3   4   1  13
    Sum   6   6   3  11   2  28
    Même démarche d'interprétation que plus haut.

    En lisant la page de documentation ?reshape2::cast, vous remarquerez que l'argiument formula peut prendre des expressions sophistiquées, avec la pratique vous serez en mesure de générer d'un seul coup quelque chose semblable au tableau en ASCII art (qui est par ailleurs élégant).

    P.S. Dans ces exemples, les IDs n'ont pas servi mais dès qu'on souhaite faire des choses avancées, il faudra d'abord faire un melt sur les données initiales, opération qui a l'avantage d'être réversible, comme ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    yyy <- melt(xxx, id.vars = "ID", measure.vars = seq(2L, 6L))
    zzz <- acast(yyy, ID ~ ...)
    print(xxx)
    print(zzz)
    > print(xxx)
       ID DEP COM CSP SEXE NOMBRE
    1   A   1   1   1    1      2
    2   B   1   1   2    1      3
    ...
    > print(zzz)
      DEP COM CSP SEXE NOMBRE
    A   1   1   1    1      2
    B   1   1   2    1      3
    ...

  5. #5
    Membre éclairé
    Inscrit en
    Novembre 2003
    Messages
    554
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 554
    Par défaut
    Ok, merci.

    C'est vrai que c'est moins sympa que ce que peut faire une 'proc tabulate' sous SAS, mais je vais essayer de me l'approprier.

    Bonne fin de journée

  6. #6
    Membre expérimenté
    Homme Profil pro
    Bioinformaticien
    Inscrit en
    Octobre 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Bioinformaticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 126
    Par défaut
    Je ne pratique pas le SAS, je viens de jeter un coup-d’œil à proc tabulate et il me semble que le fameux ASCII art était génére automatiquement avec SAS. Le paquet pander permet de formater les sorties de la sorte.
    Là où R est excellent, c'est dans l'exploration graphique des données. L'exemple que vous avez est parfait pour les tableaux de contingences multi-variées qui, en plus, sont bien intégrées avec l'interface ?stats::formula (une syntaxe similaire à ce que j'indiquais plus haut). Voici ce que ça peut donner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    library("vcd")
     
    # Dans l'exemple, vous aviez ignoré la variable NOMBRE. De même, je la gomme.
    zzz <- xtabs(~ ., xxx[, -5L])
     
    print(addmargins(zzz))
     
    mosaic(zzz, shade = TRUE, highlighting = "SEXE")
    Nom : mosaic_plot.png
Affichages : 3424
Taille : 7,6 Ko

    Il paraît qu'une image vaudrait plus qu'un millier de caractères ASCII ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. tableaux croisés dynamiques avec colonnes éditables
    Par raph_rf dans le forum Conception
    Réponses: 12
    Dernier message: 07/11/2019, 01h53
  2. [OpenOffice][Tableur] Tableaux croisés dynamiques avec calc
    Par y_lebourhis dans le forum OpenOffice & LibreOffice
    Réponses: 1
    Dernier message: 15/01/2013, 07h32
  3. [XL-2003] Instabilité des classeurs avec des Tableaux Croisés Dynamiques
    Par oohcalme dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 04/08/2009, 11h45
  4. Problème lors de copie de classeur avec Tableaux croisés dynamiques
    Par melouille56 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 11/04/2008, 17h01
  5. Tableaux croisés dynamiques et graphiques
    Par Marmouz dans le forum Access
    Réponses: 1
    Dernier message: 24/11/2005, 15h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo