Dans un
article précédent
, nous avons appris à lire des données brutes externes. Aujourd'hui, nous ferons connaissance avec l'opérateur SET, qui lit les ensembles de données SAS standard (SAS Data Set), apprendra à créer des tranches de données, à configurer des attributs persistants et à découvrir également certaines fonctions SAS utiles. Encore une fois, je vais essayer de présenter le matériel dans le langage le plus simple possible, en utilisant autant d'exemples que possible.
Disons que les données sont stockées au format EXCEL dans le répertoire
C: \ workshop \ habrahabr . Nous importons la feuille de calcul, en créons une tranche, créons de nouvelles colonnes calculées à l'aide des fonctions SAS, puis divisons cet ensemble de données en deux.
Importez une feuille de calcul et définissez un filtre
Le fichier Excel est stocké dans le répertoire ci-dessus et ressemble à ceci:
Extrait de fichier:
Nous appliquons la procédure
PROC IMPORT pour convertir une feuille de calcul en un ensemble de données SAS:
options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company replace; getnames=yes; run;
L'option
validvarname = V7 définit les noms de champs corrects du point de vue SAS: remplace tous les caractères non valides par des traits de soulignement. Les règles de dénomination des variables se trouvent dans la
leçon 1.Nous réglons le filtre immédiatement lors de la lecture d'un fichier externe, par exemple, nous sélectionnons uniquement les observations pour lesquelles la date de fin n'est pas manquante. Notez la syntaxe du paramètre where.
options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company (where=(End_Date not is missing)) replace; getnames=yes; run;
Considérons en détail les opérateurs de l'étape PROC IMPORT:
Fichier de données - définit le chemin d'accès complet et le nom du fichier externe
Dbms - Définit le type de données à importer.
Out - identifie l'ensemble de données de sortie SAS avec un nom SAS à un ou deux niveaux (nom de bibliothèque et nom d'ensemble de données).
Remplacer - Remplace un ensemble de données SAS existant.
Getnames - Indique si PROC IMPORT génère des noms de variables SAS à partir des valeurs de données dans la première ligne du fichier externe d'entrée.
Exécutez l'étape PROC IMPORT et examinez le journal:
Imprimez l'ensemble de données SAS résultant:
proc print data=work.company noobs; run;
Le résultat de la procédure PROC PRINT est illustré ci-dessous:
Fragment:
Toujours dans SAS UE, vous pouvez utiliser l'onglet Résultats pour afficher l'ensemble de données SAS importé.
Lecture de jeux de données SAS
La lecture de l'ensemble de données SAS est implémentée à l'étape DATA à l'aide de l'instruction
SET :
Considérez la syntaxe générale de l'instruction SET:
SET<SAS-data-set(s) <(data-set-options(s) )> > <options>
Si vous ne spécifiez pas de jeu de données dans l'instruction SET, il lit les observations du dernier jeu de données SAS créé.
Dans l'instruction SET, vous pouvez spécifier plusieurs ensembles de données; dans ce cas, les ensembles de données SAS seront ajoutés l'un sous l'autre (similaire à UNION dans SQL).
De plus, à l'étape DATA, il peut y avoir deux instructions SET, auquel cas les tables sont jointes par une colonne commune. Vous pouvez en savoir plus sur les deux instructions SET dans
cet article , par exemple.
Le code le plus simple pour créer une copie de l'ensemble de données SAS est le suivant:
data company1; set company; run;
Configuration d'un descripteur de jeu de données SAS
Vous pouvez examiner le descripteur de l'ensemble de données SAS à l'aide de la procédure PROC CONTENTS (
voir la leçon 2 ). Dans ce didacticiel, nous allons imprimer le composant descripteur à l'aide de la procédure
PROC DATASETS :
proc datasets library=work nolist; contents data=company order=varnum; quit;
Un fragment des résultats:
Définissez un format constant pour les variables Travel_Expenses et Budget:
data company; set company; format Travel_Expenses Budget dollar10.2; run;
Vérifiez les attributs des jeux de données SAS:
proc datasets library=work nolist; contents data=company order=varnum; quit;
Création de colonnes calculées
Toutes les fonctions SAS peuvent être explorées dans les fonctions
SAS 9.4 et les routines CALL: référence, cinquième édition .
De plus, s'il n'y a pas de fonction appropriée pour effectuer une tâche particulière, vous pouvez utiliser la procédure
PROC FCMP et créer votre propre fonction.
Dans cette leçon, nous explorerons les trois fonctions YRDIF, SUM et CATS.
Pour calculer la différence de dates en années, nous utiliserons
la fonction YRDIF .
Permettez-moi de vous rappeler qu'une date au format SAS est le nombre de jours commençant le 1er janvier 1960 (
voir leçon 1 ). Sur les données présentées, nous devons calculer le temps d'exécution:
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); format Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Veuillez noter qu'en utilisant le format 3.1 pour la variable Lead_Time, nous avons arrondi les valeurs calculées dans le rapport (!) À 1 décimale. L'opérateur de format
ne modifie pas la valeur dans l'ensemble de données SAS!
Un fragment des résultats:
Ensuite, nous calculons le coût du travail sans frais de déplacement:
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Un fragment des résultats:
Dans le cadre de notre tâche, nous avons calculé le coût du travail sans tenir compte des frais de déplacement sans utiliser la fonction. Il n'y a aucune valeur manquante dans notre tableau, si l'une des variables (Budget ou Travel_Expenses) avait une valeur manquante, le résultat était «mission».
Par exemple:
Créez un ensemble de données de test:
data test; input Budget Travel_Expenses; datalines; 12345 233 . 345 12543 . ;
Calculez la différence des variables Budget Travel_Expenses
data test; set test; value=Budget-Travel_Expenses; run;
Le résultat de cette étape:
Afin d'obtenir le résultat correct, vous pouvez utiliser la fonction
SUM .
Cette fonction appartient à la catégorie des fonctions
statistiques descriptives . Les fonctions de statistiques descriptives
ignorent les valeurs manquantes.
Écriture de code via SUM:
data test; set test; value=sum(Budget,-Travel_Expenses); run;
Dans ce cas, le résultat de l'étape est le suivant:
La troisième colonne calculée est l'adresse e-mail du responsable. Il peut être "assemblé" à partir des colonnes Manager_FirstName, Manager_LastName et des valeurs
habr .com
Vous pouvez utiliser
la fonction CATS pour combiner des valeurs de texte sur une seule ligne.
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Un fragment des résultats:
Examinons le descripteur de l'ensemble de données créé:
proc contents data=work.company1 varnum; run;
Fragment de poignée:
Faites attention à la longueur de la variable Email. Elle est de 200 octets, c'est la longueur par défaut renvoyée par la fonction CATS. Si nous examinons les attributs des variables Manager_FirstName et Manager_LastName, nous pouvons nous assurer que la longueur de chaîne 8 + 6 + '@ habr.com' est suffisante pour la variable Email, c'est-à-dire 9 autres octets, total 23. Pourquoi devrais-je faire attention à cela? Tous les caractères manquants atteignent des espaces, ce qui affecte la taille de l'ensemble de données et affectera les performances sur de grandes quantités de données.
Afin de définir explicitement la longueur de la variable Email, vous devez utiliser l'opérateur LENGTH:
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Fragment de poignée
Créez une colonne détaillée basée sur la variable Lead_Time, en tenant compte des conditions suivantes:
- Si la valeur de la variable Lead_Time est inférieure à 1, la colonne Détail a une valeur inférieure à 1 an.
- Si la valeur de la variable Lead_Time est comprise entre 1 et 2, y compris les bordures, la colonne Détail a une valeur de 1 à 2 ans.
- Si la valeur de la variable Lead_Time est comprise entre 2 et 3, à l'exclusion de 2, la colonne Détail a une valeur de 2-3 ans.
- Si la valeur de la variable Lead_Time est comprise entre 3 et 4, à l'exclusion de 3, la colonne Détails a une valeur de 3-4 ans.
- Si la valeur de la variable Lead_Time est comprise entre 4 et 5, à l'exclusion de 4, la colonne Détail a une valeur de 4 à 5 ans.
- Dans tous les autres cas, la colonne Détail a une valeur supérieure à 5 ans.
Vous pouvez créer une colonne détaillée de différentes manières, par exemple, l'option la plus simple et la plus évidente consiste à utiliser le traitement conditionnel. Il peut être implémenté à l'aide des opérateurs suivants:
- IF-THEN-ELSE
- ELSE IF
- SELECT-WHEN
Pour de grandes quantités de données, il est plus efficace d'utiliser les deux dernières options.
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='4-5 years'; else detail='above 5 years'; run;
Ajoutez une condition qui sélectionne uniquement les observations dans lesquelles la valeur de la variable Détail n'est pas égale à «au-dessus de 5 ans». Lorsque vous utilisez where comme filtre, une erreur de syntaxe se produit:
La clause where n'est pas utilisée pour les colonnes calculées. Pour sélectionner les variables dont nous avons besoin, nous avons besoin d'une instruction IF sélective. Il annule la sortie de l'observation dans l'ensemble de données créé:
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run;
Notez également que l'instruction IF sélective nécessite un opérateur arithmétique. Nous ne pouvons pas écrire, par exemple, comme ceci:
if detail contains 'above 5 years';
Une erreur sera affichée dans le journal:
Configurez l'ensemble de données SAS.
Les variables Manager_FirstName et Manager_LastName ne doivent pas être présentes dans le nouvel ensemble de données SAS. Cette exigence est implémentée à l'aide du paramètre DROP, et l'opérateur DROP peut également être utilisé.
data company1 (drop=Manager_FirstName Manager_LastName); set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run;
Nous divisons le jeu de données SAS créé en deux selon la condition donnée
En une seule étape DATA, vous pouvez créer plusieurs jeux de données SAS. Créez un ensemble de données distinct pour chaque pays.
Par exemple, pour vérifier les valeurs de la colonne Pays, vous pouvez utiliser la procédure
PROC FREQ .
proc freq data=company1; table Country /nocum nopercent; run;
Cette étape considère le nombre de fois où une valeur particulière de la variable Country apparaît dans l'ensemble de données SAS spécifié dans le paramètre data =.
Le résultat de cette étape sera le suivant:
Ainsi, nous allons créer deux ensembles de données à une étape DATA en utilisant l'opérateur OUTPUT et le traitement conditionnel:
data US AU; set work.company1; if Country='AU' then output AU; if Country='US' then output US; run;
Exécutez le code et consultez LOG:
Il s'agit brièvement de la lecture et de la configuration des jeux de données SAS. Dans le prochain article, nous vous présenterons la combinaison d'ensembles de données à l'aide des instructions MERGE et SET.
Et en tant que PS, je vous rappelle la structure de nos cours SAS BASE:
Articles déjà publiés:
- Bases de la programmation sur SAS BASE. Leçon 1.
- Bases de la programmation sur SAS BASE. Leçon 2. Accès aux données
- Bases de la programmation sur SAS BASE. Leçon 3. Lecture de fichiers texte.
- Vous venez d'apprendre la quatrième leçon.
Dans les articles suivants, je voudrais souligner des problèmes tels que la jonction de tables dans SAS Base (fusion, définition), le traitement conditionnel, les boucles, les fonctions SAS, la création de formats personnalisés, la macro SAS, PROC SQL.

Je serai heureux de vos commentaires dans les commentaires! Quels autres sujets aimeriez-vous voir dans les articles?