Etape DATA sous SAS
Créez, lisez et manipulez vos tables SAS avec l'étape DATA
Nous avons jusqu'ici, dans nos articles, évoqué principalement l'étape PROC qui permet le traitement, l'analyse et l’édition de résultats. Ici nous allons étudier l'étape DATA qui va nous permettre d'aller plus loin dans la manipulation des données.
Lecture et création d'une table
Associée à l'instruction SET, l'étape DATA va nous permettre de copier les données d'une table existante vers une nouvelle table.
data mycars;
set sashelp.cars;
run;
Le code ci-dessus va créer une table mycars en copiant la table cars issue de la bibliothèque standard sashelp.
Si la table mycars n'existe pas déjà, DATA va la créer. Dans le cas contraire, elle sera écrasée. Par ailleurs,
si aucune bibliothèque n'est précisée, comme c'est notre cas, la bibliothèque de travail (WORK) sera utilisée.
Quant à elle, l'instruction SET nous permet d'indiquer la table source, qui doit donc obligatoirement exister. SET va
procéder à une lecture séquentielle de toutes les observations et variables de la table indiquée.
Au final, le bloc descripteur et les observations de la table nouvellement créée (ici mycars) seront identiques à la
table d'origine (sashelp.cars).
Sélection des variables
Nous pourrions vouloir ne copier qu'une partie des variables, par exemple le constructeur et le modèle de véhicule dans l'exemple qui nous concerne. Ceci est possible via l'instruction KEEP à ajouter à la suite de SET. Il nous suffit alors de préciser le nom des colonnes à conserver.
data mycars;
set sashelp.cars;
keep make model;
run;
Sélection des observations sources
De même, nous pourrions vouloir filtrer les observations à copier. L'instruction SELECT va nous permettre de répondre à cela. Ceux qui ont des notions SQL ne seront pas dépaysés car la logique est la même. Ci-dessous un exemple dans lequel nous avons, tout en conservant seulement le constructeur et le modèle en sortie, filtré les observations sur le type de véhicule (berline ou sport) et la puissance du moteur (entre 350 et 400 chevaux).
data mycars;
set sashelp.cars;
keep make model;
where (type='Sedan' or type='Sports') and horsepower between 350 and 400;
run;

Création de nouvelles variables
L'étape DATA peut aussi nous permettre d'ajouter de nouvelles variables dans notre table. Ces variables peuvent être des constantes, des valeurs calculées ou encore le résultat de fonctions. Ci-dessous un exemple :
data mycars;
set sashelp.cars;
keep Make Model invoice tax invoice_with_tax seller vendor date_update time_update;
tax = 412;
invoice_with_tax = invoice + tax;
seller = 'Auto PARIS';
vendor = ifc(Make = 'Audi', 'John', 'Franck');
date_update="12DEC2022"d;
time_update="11:00:00"t;
run;
proc print data=mycars;
format date_update date9.;
format time_update time5.;
format tax invoice_with_tax dollar10.0;
run;
Dans le code ci-dessus, nous avons, via l'instruction SET, repris la table cars standard, puis demandé
à ne conserver que quelques variables, dont celles que nous allons ajouter. Vous noterez, par conséquent,
que l'instruction keep peut très bien se situer avant l’initialisation des nouvelles variables.
Ensuite, nous avons déclaré une constante numérique (tax), une variable calculée (invoice_with_tax) qui reprend
la valeur de la colonne d'origine invoice. Nous avons également ajouté une constante chaine (seller) puis une autre
issue d'un test logique sous sa présentation ternaire. Ici tous les modèles Audi sont vendus par John, les autres
par Franck.
Enfin nous terminons avec deux constantes date et temps (date_update et time_update).
Nous avons pris soin d'implémenter une PROC PRINT pour que les dates et autres montants apparaissent sous un format
présentable.
Voici un extrait du résultat :

Sélection des observations cibles
Nous avons évoqué plus haut la possibilité de filtrer les observations à copier via une instruction SELECT. Celle-ci
ne s'applique que sur les variables d'origine, or nous pourrions vouloir effectuer une sélection sur la base de
variables nouvellement ajoutées. Nous allons pour cela utiliser l'instruction IF.
Quelques remarques concernant l'instruction IF :
- Tout d'abord, IF fonctionne aussi bien sur les nouvelles variables que sur les variables héritées,
- Il faut veuiller à positionner une instruction IF après l'initialisation d'une variable qu'elle filtre,
- L'instruction IF ne peut être utilisée que dans une étape DATA, on ne pourra le faire dans une étape PROC,
- Enfin, il est tout à fait possible d'utiliser plusieurs instructions IF dans une même étape DATA. De même,
on pourra cumuler des instructions SELECT et IF.
data mycars;
set sashelp.cars;
keep Make Model invoice tax invoice_with_tax;
tax = 412;
invoice_with_tax = invoice + tax;
if invoice_with_tax > 90000;
run;
proc print data=mycars;
format tax invoice_with_tax dollar10.0;
run;
Dans l'exemple ci-dessus, nous avons quelque peu édulcoré le code précèdent pour ne conserver que l'initialisation de la taxe, puis du prix taxe comprise. Une instruction IF a été ajoutée après le calcul du prix pour ne conserver que les véhicules dont le prix dépasse 90.000 dollars.
Création d'un set de données
Il est possible, via une étape DATA, de créer un petit jeu de données sans copie d'une table existante. Cette option
est bien sûr à réserver pour les tests unitaires par exemple ou les jeux de données réduits. Dans le cas contraire, il
convient de charger un fichier tout simplement.
Procédons, par exemple, à la création d'une table des vendeurs dans laquelle nous voulons stocker le nom de 3 individus,
ainsi que leurs âges :
data vendor;
input indice nom $ age ;
datalines;
1 John 43
2 Franck 26
3 Paul 32
;
run;

Vous noterez le signe $ après la variable nom qui stipule à SAS qu'il s'agit d'une chaine. Nous n'avons pas précisé de format mais nous aurions pu puisque la fonction INPUT le permet.
Jointure sur deux jeux de données
Nous terminerons notre tour d'horizon de l'étape DATA avec l'instruction MERGE qui va nous permettre d'effectuer une jointure de deux tables. Nous avons déjà une table vendor créée précédemment, ajoutons une table speciality :
data speciality;
input indice marque $ ;
datalines;
1 Audi
3 Ford
;
run;
A présent, nous allons joindre les tables vendor et speciality dans une nouvelle table vendor_specialized sur la base de la colonne indice. Comme vous le constatez il n'y a pas d'indice 2 dans la table speciality, nous devrions par conséquent avoir une valeur vide, voyons cela :
data vendor_specialized;
merge vendor speciality;
by indice;
run;

Retrouvez dans la rubrique "Nos datasets" toutes les données dont vous aurez besoin pour tester et pratiquer !