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 de (gH)