SAS2R – Episode 4 : La PROC TRANSPOSE

sas vers R episode 4
Tags : Actualités, Ressources
Date :

Pour le quatrième épisode de notre série SAS2R, nous nous attaquons aujourd’hui en toute logique à la PROC TRANSPOSE ; Après avoir importé, créé, fusionné les données dont nous avions besoin pour procéder à notre analyse, vient l’étape de la mise en forme de nos données. Nous avons déjà évoqué dans un autre article ce qu’était le pivot, et comment utiliser les fonctions pivot_longer() et pivot_wider() du package {tidyr}, et je vous invite à le lire afin d’aller plus loin. Nous allons ici nous focaliser sur la traduction de la PROC TRANSPOSE en R.

Les options de la PROC TRANSPOSE dans SAS

La PROC TRANSPOSE permet de modifier la forme des données, d’un format dit “vertical” vers un format dit “horizontal”. Elle prend plusieurs paramètres en entrée :

  • DATA : le nom de la table SAS à manipuler.
  • DELIMITER ou DELIM : spécifie un délimiteur à utiliser dans la construction des noms des variables transposées : le délimiteur sera inséré entre les valeurs des variables si plusieurs variables ont été spécifiées dans l’instruction ID
  • LABEL : spécifie un label pour la variable transposée dans la table de sortie.
  • LET : autorise les valeurs en double d’une variable ID. Dans ce cas, PROC TRANSPOSE transpose l’observation qui contient la dernière occurrence d’une valeur d’ID particulière dans l’ensemble de données ou le groupe BY.
  • NAME : spécifie le nom de la variable dans l’ensemble de données de sortie qui contient le nom de la variable qui est transposée.
  • OUT : nom de la table de sortie
  • PREFIX : spécifie un préfixe à ajouter aux noms des variables transposées
  • SUFFIX : spécifie un suffixe à ajouter aux noms des variables transposées

Source : https://support.sas.com/documentation/cdl/en/proc/61895/HTML/default/viewer.htm#a000063663.htm

Premier exemple simple

Considérons le jeu de données suivant :

data_vin <- tibble(
  cepage = c("Malbec", "Cabernet Sauvignon", "Cabernet Franc", "Merlot", "Pinot Noir", "Syrah"),
  environnement =  sample(paste0("env", 1:3), size = 6, replace = TRUE),
  note = runif(6, 0, 5)
)
data_vin
## # A tibble: 6 x 3
##   cepage             environnement  note
##   <chr>              <chr>         <dbl>
## 1 Malbec             env1          1.81 
## 2 Cabernet Sauvignon env1          3.90 
## 3 Cabernet Franc     env1          1.83 
## 4 Merlot             env2          3.89 
## 5 Pinot Noir         env3          2.65 
## 6 Syrah              env2          0.878

L’utilisation la plus simple que nous pouvons faire de la PROC TRANSPOSE est la suivante :

PROC TRANSPOSE DATA = data_vin OUT = transp1;
RUN;

Ce qui renvoie :

##   _NAME_     COL1    COL2     COL3     COL4     COL5      COL6
## 1   note 1.812944 3.90306 1.826749 3.894421 2.651929 0.8783724

Par défaut, la PROC TRANSPOSE ne transpose que les variables numériques. Ainsi, ces lignes de code renvoient une table contenant la variable note transposée. En R, la fonction t() transpose la totalité de la table, et les noms des colonnes deviennent les noms des lignes :

t(data_vin)
##               [,1]        [,2]                 [,3]             [,4]        [,5]         [,6]       
## cepage        "Malbec"    "Cabernet Sauvignon" "Cabernet Franc" "Merlot"    "Pinot Noir" "Syrah"    
## environnement "env1"      "env1"               "env1"           "env2"      "env3"       "env2"     
## note          "1.8129435" "3.9030599"          "1.8267488"      "3.8944205" "2.6519293"  "0.8783724"

Pour obtenir le même résultat qu’avec la PROC TRANSPOSE, on peut procéder comme suit :

transp1 <- data.frame("_NAME_" =  "note", t(data_vin$note), check.names = FALSE)
colnames(transp1)[2:ncol(transp1)] <- paste0("COL", 1:(ncol(transp1) - 1))
transp1
##   _NAME_     COL1    COL2     COL3     COL4     COL5      COL6
## 1   note 1.812944 3.90306 1.826749 3.894421 2.651929 0.8783724

Bon, ce tableau n’est pas très utilisable en l’état : la variable note est tirée en largeur dans différentes colonnes mais elles n’ont pas de noms explicites.
Si l’on souhaite nommer la première colonne, au lieu du NAME donné par défaut en SAS, et que les autres colonnes soient préfixées par autre chose que COL, on utilise en SAS les options NAME et PREFIX comme suit :

PROC TRANSPOSE DATA = data_vin NAME = nom_var PREFIX = note OUT = transp2;
RUN;

En R, le code n’en est que très peu modifié, puisque nous devions déjà imposé les valeurs par défaut de SAS. On a donc :

transp2 <- data.frame(nom_var =  "note", t(data_vin$note), check.names = F)
colnames(transp2)[2:ncol(transp2)] <- paste0("note", 1:(ncol(transp2) - 1))
transp2
##   nom_var    note1   note2    note3    note4    note5     note6
## 1    note 1.812944 3.90306 1.826749 3.894421 2.651929 0.8783724

Ce n’est pas très “intuitif” comme utilisation de R… Basculons dans le tidyverse pour un cas d’usage un peu plus proche de ce qui passe vraisemblablement dans le quotidien avec vos données.

Nommer les colonnes transposées

Continuons avec le même exemple. On souhaite maintenant nommer les colonnes créées, mais en fonction des valeurs de la variable cepage de notre jeu de données initial. En SAS, c’est l’option ID qui nous permet de faire cela :

PROC TRANSPOSE DATA = data_vin NAME = nom_var OUT = transp3;
  ID cepage;
RUN;

En R, on utilisera la fonction pivot_wider() du package tidyr comme suit :

transp3 <- data_vin[,c("cepage", "note")] %>%
  pivot_wider(names_from = cepage, values_from = note)
transp3 <- cbind(nom_var = "note", transp3)
transp3
##   nom_var   Malbec Cabernet Sauvignon Cabernet Franc   Merlot Pinot Noir     Syrah
## 1    note 1.812944            3.90306       1.826749 3.894421   2.651929 0.8783724

Il est nécessaire ici de restreindre les données d’entrée aux colonnes cepage et note car si on garde la variable environnement, le résultat sera le suivant :

transp3 <- data_vin %>%
  pivot_wider(names_from = cepage, values_from = note)
transp3
## # A tibble: 3 x 7
##   environnement Malbec `Cabernet Sauvignon` `Cabernet Franc` Merlot `Pinot Noir`  Syrah
##   <chr>          <dbl>                <dbl>            <dbl>  <dbl>        <dbl>  <dbl>
## 1 env1            1.81                 3.90             1.83  NA           NA    NA    
## 2 env2           NA                   NA               NA      3.89        NA     0.878
## 3 env3           NA                   NA               NA     NA            2.65 NA

Restructurer les données

Supposons maintenant que l’on souhaite modifier la structure de nos données de telle sorte que les valeurs de la variable environnement constituent les colonnes de notre jeu de données. Ici, l’utilisation de BY dans la PROC TRANSPOSE impose le tri préalable des données, excepté si on le spécifie via l’option NOTSORTED. L’option DROP permet de supprimer une colonne non nécessaire qui aurait pour unique valeur ‘note’ :

PROC TRANSPOSE DATA = daya_vin OUT= transp4 (DROP=_NAME_);
  BY cepage NOTSORTED;
  ID environnement;
  VAR note;
RUN;

Dans R, on utilise de nouveau la fonction pivot_wider(), en gardant cette fois-ci toutes les variables :

transp4 <- data_vin %>% 
  pivot_wider(names_from = environnement, values_from = note)
transp4
## # A tibble: 6 x 4
##   cepage              env1   env2  env3
##   <chr>              <dbl>  <dbl> <dbl>
## 1 Malbec              1.81 NA     NA   
## 2 Cabernet Sauvignon  3.90 NA     NA   
## 3 Cabernet Franc      1.83 NA     NA   
## 4 Merlot             NA     3.89  NA   
## 5 Pinot Noir         NA    NA      2.65
## 6 Syrah              NA     0.878 NA

Plutôt lisible, non ?

Utilisation de deux variables pour le nom des nouvelles colonnes

L’idée est ici de créer de nouvelles variables à partir des combinaisons de deux variables du jeu de données initial, et donc de renseigner deux noms de colonnes à l’option ID, ainsi qu’un délimiteur via l’option DELIMITER :

PROC TRANSPOSE DATA = data_vin DELIMITER = _ OUT = transp5 (DROP=_NAME_);
  ID cepage environnement;
RUN;

Dans la même logique, on spécifiera les deux noms de colonnes concernées au niveau du paramètre names_from de la fonction pivot_wider() :

transp5 <- data_vin %>% 
  pivot_wider(
    names_from = c(cepage, environnement), 
    names_sep = "_",
    values_from = note
  )
transp5
## # A tibble: 1 x 6
##   Malbec_env1 `Cabernet Sauvignon_env1` `Cabernet Franc_env1` Merlot_env2 `Pinot Noir_env3` Syrah_env2
##         <dbl>                     <dbl>                 <dbl>       <dbl>             <dbl>      <dbl>
## 1        1.81                      3.90                  1.83        3.89              2.65      0.878

Vous voici équipés pour pivoter un jeu de données en largeur dans R et diffuser de l’information contenue en ligne dans les colonnes !

Pour finir…

Après avoir évoqué les calculs de statistiques de base, les opérateurs et les fonctions, l’import de données et les fusions de tables, cet article sur la mise en forme des données conclut notre série « transition de SAS vers R« , qui j’espère, aura pu répondre à vos questions sur la traduction des principales procédures de SAS en R. Finalement, importer, manipuler, transformer sont autant de compétences indispensables qui constituent le socle de connaissances du « data scientist ». Peut-être pouvez-vous compléter cette série en regardant comment visualiser ses données avec ggplot2 dans R, ou encore faire ses premiers pas en machine learning ? S’il est bien une force de R comparativement à SAS, c’est à quel point il est aisé également de communiquer sur ses résultats que ce soit via des rapports d’analyses automatisés ou des applications web interactives. Être à même de tout réaliser en R, de l’import des données à la communication des résultats sur une application web interactive est indéniablement un atout de R… et un super pouvoir du data scientist !

D’ailleurs, saviez-vous que nous avons décliné ces super pouvoirs en certifications de qualification professionnelle éligibles au CPF ? N’hésitez pas à consulter les autres articles du blog qui vous permettront de vous perfectionner en R ou contactez-nous pour aller plus loin dans votre formation !

Dans la même série :

SAS2R – Episode 1 : PROC SUMMARY, PROC MEANS`
SAS2R – Episode 2 : Opérateurs et fonctions de base
SAS2R – Episode 3 : Etape DATA, PROC SQL


À propos de l'auteur


Commentaires

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


À lire également