Valid XHTML     Valid CSS2    

Introduction à la programmation R (exercices)

Séance de révision numéro 2

                     gilles.hunault "at" univ-angers.fr

 

Border un tableau avec les pourcentages en lignes et en colonnes

On utilise cette fois des données fictives de cout par ville et par mois. On voudrait ajouter en fin de tableau une colonne avec le pourcentage des lignes par rapport au total et en début de tableau une ligne avec le pourcentage des colonnes par rapport au total. Voici ce qu'on devrait obtenir pour les données du fichier pcts.txt :


     Données lues :
     
                Angers Nantes
     Janvier        30     20
     Février        80     70
     Mars           25     25
     
     Le total général est  250
     
     Données consolidées :
     
                Angers Nantes % du total
     % du total   54 %   46 %       <NA>
     Janvier        30     20       20 %
     Février        80     70       60 %
     Mars           25     25       20 %
     

On utilisera bien sûr deux boucles POUR avant de chercher une solution sans boucles.

Solution

Le chargement des données se fait via read.table() avec les bonnes options. Une fois la matrice de résultats correctement dimensionnée et initialisée, il faut prendre soin à bien calculer les indices de résultats, soit le code :


     ## ajout de pourcentages en lignes et en colonnes
     
     # 1. lecture et affichage des données initiales
     
     url     <- "http://forge.info.univ-angers.fr/~gh/wstat/Programmation_R/Programmation_introduction/pcts.txt"
     dataOrg <- read.table(file=url,encoding="latin1",header=TRUE,row.names=1)
     nbLig   <- nrow(dataOrg)
     nbCol   <- ncol(dataOrg)
     
     cat("Données lues :\n\n")
     print(dataOrg)
     
     # 2. structure d'accueil des résultats
     
     nbLigRes <-  nbLig+1
     nbColRes <-  nbCol+1
     dataRes  <- data.frame(matrix(NA,nrow=nbLigRes,ncol=nbColRes))
     
     # 3. recopie des données initiales avec leurs noms en lignes et en colonne
     
     dataRes[ (2:nbLigRes) , 1:nbCol ] <- dataOrg
     row.names(dataRes)[2:nbLigRes]    <- row.names(dataOrg)
     names(dataRes)[1:nbCol]           <- names(dataOrg)
     
     # 4. total général
     
     totGen <- sum( rowSums(dataOrg))
     cat("Le total général est ",totGen,"\n")
     
     # 5. colonne de pourcentage pour chaque ligne avec une boucle POUR
     
     names(dataRes)[nbColRes] <- "% du total"
     for (ilig in (1:nbLig)) {
       totLig <- sum( dataOrg[ilig,] )
       pctLig <- round(100*totLig/totGen)
       dataRes[(1+ilig),nbColRes] <- paste(pctLig,"%")
       # pour debug : cat(" ligne ",ilig," somme ",totLig," pct = ",pctLig,"\n")
     } # fin pour ilig
     
     # 6. ligne de pourcentage pour chaque colonne avec une boucle POUR
     
     row.names(dataRes)[1] <- "% du total"
     for (icol in (1:nbCol)) {
       totCol <- sum( dataOrg[,icol] )
       pctCol <- round(100*totCol/totGen)
       dataRes[1,icol] <- paste(pctCol,"%")
       # pour debug : cat(" colonne ",icol," somme ",totCol," pct = ",pctCol,"\n")
     } # fin pour icol
     
     # 7. affichage des résultats
     
     cat("\n")
     cat("Données consolidées :\n\n")
     print(dataRes)
     

Pour éviter d'écrire des boucles, on peut passer par les fonctions apply() et sapply(). Voici ce qui change :


     # 5. colonne de pourcentage pour chaque ligne avec apply
     
     names(dataRes)[nbColRes] <- "% du total"
     ligPct <- function(ligne) {  return( round(100*sum(ligne)/totGen) ) }
     dataRes[(2:nbLigRes),nbColRes] <- paste( apply(F=ligPct,X=dataOrg,M=1),"%" )
     
     # 6. ligne de pourcentage pour chaque colonne avec sapply
     
     row.names(dataRes)[1] <- "% du total"
     colPct <- function(colonne) { return( round(100*sum(colonne)/totGen) ) }
     dataRes[1,(1:nbCol)] <- paste( sapply(F=colPct,X=dataOrg),"%" )
     

On pourra apprécier la concision de ce code sans les boucles.

 

Retour à la page principale du cours.

 

 

retour gH    Retour à la page principale de   (gH)