Archive for the ‘proc sql’ Category

h1

SAS 9.2. : WARNING avec PROC SQL et l’option UNDO_POLICY=NONE

janvier 6, 2013

Depuis SAS 9.2, un nouveau WARNING apparaît dans la log quand le nom de la table SAS d’entrée est le même que le nom de la table SAS de sortie. Pour éviter ce message, l’option undo_policy=none est à ajouter dans l’instruction proc sql;. SAS support prévient néanmoins que l’usage du même nom en entrée et en sortie présente un risque et que l’option enlève l’avertissement mais pas le risque.

1. Le message dans la log

WARNING: CREATE TABLE statement recursively references the target table

 

2. Exemple

Ce code générerait le warning avec SAS 9.2 si l’option undo_policy=none n’était pas utilisée.

proc copy in=sashelp out=work;
   select class;
run;

proc sql undo_policy=none;
   create table class as 
   select name, age
   from class;
quit;

 

En savoir plus

h1

Des options pour se débarrasser de WARNING de SAS 9.2

août 18, 2010

Avec SAS 9.1.3 et SAS9.2 de nouveaux warning apparaissent. En voici deux que vous pouvez faire disparaître dans le cas où ils ne reflètent pas un problème dans votre programme.

  1. Avec PROC SQL, je crée une nouvelle table du même nom que la table source.
  2. Dans un data set je réduis la longueur d’une variable

1. Utiliser le même nom de data set en entré et en sortie avec PROC SQL

Pour illustrer le sujet, je vais d’abord créer un data set appelé ONE avec deux variables X et Y.

data one;
x=‘A’;
y=‘B’;
run;

Ensuite je vais créer avec PROC SQL un nouveau data set du même nom ONE qui ne contiendra que la variable X.

proc sql;
create table one as
select x
from one;
quit;

Le message dans la log ressemble à ceci:
WARNING: This CREATE TABLE statement recursively reference the target table. A consequence of this is a possible data integrity problem.

Pour ne plus avoir ce message dans la log, ajouter l’option UNDO_POLICY=NONE

proc sql undo_policy=none;
create table one as
select x
from one;
quit;

Ce cas existe depuis SAS 9.1.3.

2. Réduire la longueur d’une variable dans une étape data

Une solution pour changer la longueur d’une variable est de définir sa longueur dans une instruction LENGTH avant de lire les données avec un SET par exemple.

Depuis SAS 9.2, si la nouvelle longueur est plus petite que l’ancienne un WARNING apparaît dans la log. Ceci est une bonne chose car cela vous permet de repérer d’éventuelles coupures (truncations) de vos données.

Dans certains cas cependant, vous savez pertinemment que le nombre de caractères dans données est au plus X et que dès lors elles ne seront pas coupées en réduisant la longueur.

Vous pouvez vous épargner le warning en encadrant votre étape data des options globales VARLENCHK=nowarn et VALENCHK=warm.

Je vous conseille d’appliquer cette option localement afin de pouvoir continuer à repérer d’autres coupures potentielles non prévues.

data two;
length x $32;
x=‘A’;
run;

data two_a;
length x $1;
set two;
run;

WARNING : Multiple lengths were specified for the variable x by input data set(s). This may cause truncation of data.

options varlenchk=nowarn;
data two_b
length x $1;
set two;
run;
options varlenchk=warn;

Notez cependant, qu’avec SAS 9.1.3 ou SAS 9.2, un warning apparaît dès lors que la variable est donnée dans une instruction BY. L’option VARLENCHK de SAS 9.2 ne vous enlèvera pas le warning. Je vous conseille donc de changer votre longueur au préalable si vous ne voulez pas ce WARNING.

data two_b;
length x $1;
set two;
by x;
run;

WARNING: Multiple lengths were specified for the BY variable x by input data sets and LENGTH, FORMAT, INFORMAT statements. This may cause unexpected results.

Lectures complémentaires :

h1

Deux manières de créer un data set vide

juillet 2, 2009

Dans un précédent article Copier la structure d’un data set et se séparer des données, nous avons vu comment récupérer la structure d’une table (data set) de référence, c’est-à-dire copier les caractéristiques des variables sans les données. Ici, vous verrez comment créer un data set, appelé EMPTY, sans données et sans se baser sur un data set de référence.

L’intérêt est de souvent de pouvoir ensuite empiler des data sets ayant des longueurs de variables. En effet la longueur d’une variable rencontrée dans le premier data set sera la longueur de référence. Il ne faut pas qu’elle soit plus petite que celle du data set suivant. Autrement le texte des observations d’après est coupé (truncated).

1. Avec une étape data

Au choix, vous avez l’instruction ATTRIB ou les différentes instructions LABEL, LENGTH, FORMAT, INFORMAT pour créer les variables du data set.

data empty;
attrib var_text   label=‘Var. caractère, longueur 20′ length=$20
var_num_dt label=‘Var. numérique, longueur 8′ format=date9.;
stop;
run;

Dans la log, SAS précisera qu’aucune valeur n’a été donné aux variables VAR_TEXT et VAR_NUM_DT.

NOTE: Variable var_text is uninitialized.
NOTE: Variable var_num_dt is uninitialized.

2. Créer un data set vide avec la procédure SQL

La procédure SQL

proc sql;
create table empty
(
var_text char(20) label=‘Var. caractère, longueur 20′ ,
var_num_dt num label=‘Var. numérique, longueur 8′ format=date9.
);
quit;

3. Voir le résultat

J’ai choisi d’ajouter l’option VARNUM à la procédure PROC CONTENTS pour afficher les données dans l’ordre

proc contents data=empty varnum;
run;

La variable VAR_TEXT apparaît en premier. Il s’agit d’une variable alphanumérique de longueur 20 sans format et ayant pour libellé : Var. caractère, longueur 20.

La seconde variable VAR_NUM_DT est numérique, de longueur 8. Le format DATE9 est appliqué dessus de manière permanente. Le libellé de cette variable est : Var. numérique, longueur 8.

The CONTENTS Procedure

Variables in Creation Order

# Variable   Type   Len Format Label

1 var_text   Char   20         Var. caractère, longueur 20
2 var_num_dt Num     8  DATE9. Var. numérique, longueur 8

Lectures complémentaires

h1

Changer la longueur d’une variable avec PROC SQL (instruction ALTER)

avril 27, 2009

En SAS, l’instruction ALTER de PROC SQL a la capacité de changer le libellé d’un data set, modifier le format/informat ou le libellé d’une variable. Mais son principale intérêt réside dans sa capacité à modifier la longueur d’une variable caractère sans changer la position de la variable dans le data set.

1. Comparaison avec deux autres méthodes : PROC DATASETS et l’étape DATA

Alors que PROC DATASETS permet de modifier le format/informat, le libellé d’une variable ou de renommer une variable, il ne permet pas de changer la longueur d’une variable.

Avec une simple étape data, il est possible de modifier la longueur de la variable en ajoutant une instruction LENGTH avant de lire les donnees avec un SET/MERGE… Mais la séquence d’affichage des variables n’est plus respecté. Il faut soit avoir sauvegardé au préalable l’ordre d’affichage (ou l’entrer manuellement, bof !), soit utiliser l’instruction ALTER de PROC SQL…

2. Quelques données pour tester soi-même

* Create two formats SEX and GENDER;
proc format;
value $ sex ‘M’=‘Male’
‘F’=‘Female’;
value $ gender ‘M’=‘Homme’
‘F’=‘Femme’;
run;

*Create a data set named CLASS ;
*based on the SASHELP.CLASS data set ;
*adding the SEX format to the SEX variable;

data class;
set sashelp.class;
format sex sex.;
run;

3. L’instruction ALTER pour modifier la longueur d’une variable

Dans l’instruction ALTER de PROC SQL, le mot-clé MODIFY introduit deux variables SEX et NAME à modifier.

proc sql;
alter table class (label=‘Changes with PROC SQL and ALTER’)
modify sex format=$gender.,
name char(20) label=‘Student Name’;
quit;

Changement le plus intéressant :

  • La longueur de la variable caractère NAME est à l’origine 8. Elle est remplacée par 20.

Quelques changements secondaires :

  • Libellé de data set : Dans l’exemple ci-dessus le data set CLASS a pour libellé ‘Changes with PROC SQL and ALTER’.
  • format de variable : Le format de la variable SEX est à l’origine $SEX. Il est ici remplacé par le format $GENDER.
  • Libellé de variabel : Le libellé de la variable NAME est ajouté. Il s’agit de ‘Student Name’.

A retenir :

  1. Seules les variables caractères peuvent avoir leur longueur changées au moyen de l’instruction ALTER.
  2. Cette instruction permet certe de modifier le format d’un data set. Néanmoins, elle ne permet pas de supprimer tous les formats d’un data set.

Lectures complementaires :

SAS Online DOC

h1

Deux méthodes pour sélectionner des données en se basant sur un second data set

janvier 26, 2009

Avec IF/SELECT/WHERE, OUTPUT/DELETE vous savez comment garder une partie des données disponible en fonction de la valeur de variables. Mais comment faire si les données servant de critère sont dans un autre data set ?

Voici un exemple :

  • D’un côté, on a un data set SAS avec tous les effets secondaires (adverse events)  de tous les patients. Un patient peut avoir plusieurs effets secondaires et donc plusieurs lignes. Il peut aussi ne pas être présent s’il aucun effect secondaire n’a été enregistré.
  • De l’autre côté on a un data set contenant seulement les patients répondant aux critères du protocol d’étude clinique (une ligne par patient).

Comment garder tous les effects secondaires de ces patients valides par protocole et seulement de ceux-là ?. SAS a deux possibilités :

  1. un MERGE dans une étape data utilisé avec son option (IN=)
  2. un PROC SQL avec la condition WHERE… IN ().

Vous trouverez un rappel sur le MERGE en lisant : « La base de la jointure de deux data sets avec MERGE« .

1. Les data sets AE_MULTI et PAT_UNIQ servent d’exemple

Une ou plusieurs lignes par patients dans le data set AE_MULTI : le data set AE_MULTI contient six effets secondaires (6 lignes d’observations) se référant à 4 patients (numéros : 1, 2, 4 et 5).

data ae_multi;
   input patref ae_id;
   datalines;
1 1
1 2
2 1
4 1
4 2
5 1
;
run

Une seule ligne par patient dans le data set PAT_UNIQ : le data set PAT_UNIQ contient trois patients (3 observations) : numéros 2, 3 et 4.

data pat_uniq;
   input patref;
   datalines;
2
3
4
;
run;

En d’autres termes, on souhaite garder les observations de AE_MULTI si et seulement si le patient est aussi enregistré dans le data set PAT_UNIQ. Trois observations sont à conserver : celles du patient 2 avec ses deux effets secondaires et celle du patient 4 avec son effet secondaire.

patref    ae_id

   2        1
   4        1
   4        2

2. Deux solutions

Dans ce cas du MERGE, on annote (flag) les données avec des variables temporaires (AE et PAT).

  • Si la valeur de PATREF est présente dans le fichier AE_MULTI, alors AE=1, sinon AE=0.
  • Si la valeur de PATREF est présente dans le fichier PAT_UNIQ, la variable PAT=1, sinon elle est égale à 0.

Si le patient est à la fois dans les deux data sets  (si AE=1 et PAT=1), alors les données sont envoyées (ouputted) dans le data set VERSION1.

Comme se sont les variables du data set AE_MULTI qui nous intéresse et non celles du data set PAT_UNIQ, on ne garde parmi les variables de PAT_UNIQ seulement la variable PATREF servant de lien et listée dans l’instruction BY.

data version1;
   merge ae_multi (in=ae)
         pat_uniq (in=pat keep=patref);
   by patref;
   if ae and pat;
run;

Avec la procédure SQL, on sélectionne toutes les données disponibles dans le data set AE_MULTI en précisant que les valeurs de la variable PATREF doit aussi être présentes dans une autre sélection, celle définie entre parenthèses.

proc sql;
   create table version2 as
      select *
      from ae_multi
      where patref in (select patref from pat_uniq);
quit;

Entre les deux méthodes, on notera deux différences :

  1. Avec le merge, il est possible de lier des data sets ayant plus d’une variable commune (by pays centre patient;).
  2. Avec la procédure SQL, on peut multiplier les données dans le WHERE. Par exemple, on pourrait à la fois choisir les patients qui sont dans le data set PAT_UNIQ et exclure les effets secondaires qui sont aussi présents dans un autre fichier que AE.
h1

5 points à retenir sur l’opérateur logique LIKE

décembre 14, 2008

Comment dire à SAS de sélectionner toutes les observations pour lesquelles une variable donnée contient le mot CASTS ? L’opérateur logique LIKE, utilisable uniquement une condition exprimée par WHERE est fait pour ce travail. Voici donc 5 points à retenir sur LIKE que vous pourrez vous même vérifier à l’aide du data set founi en bas d’article dans la rubrique « Annexe » et des exemples de la section 2.

1. Les 5 points à retenir sur LIKE

1. Trouver un texte ayant une structure donnée : Le but de LIKE est de trouver, pour une variable donnée, toutes les observations ayant une structure particulière.

2. Traiter des chaînes de caractères : LIKE s’applique à une chaîne de caractères et non à des valeurs numériques.

3. Autoriser un caractère libre : Le tiret bas (underscore : _) désigne qu’il faut absolutement un caractère à l’endroit où il est utilisé : ni plus ni moins.

4. Autoriser une chaîne de caractère libre : Le pourcentage (percent : %) accepte toute chaîne de caractère, quelque soit sa longueur, à l’endroit où le symbole apparaît. L’absence de caractère est aussi valide.

5. Appliquer LIKE dans un WHERE : LIKE s’utilise uniquement avec WHERE dans une étape data ou dans la procédure SQL. Il ne fonctionnera pas avec IF.

2. Quelques exemples

Un exemple avec les pourcentages : Dans ce premier exemple, on sélectionne toutes les lignes d’observations où la variable TEST_LAB contient le mot CASTS en majuscule. Il est possible de prendre une observation contenant du texte ou des blancs avant le mot CASTS et/ou après le mot CASTS.

data casts;
   set lab (where=(test_lab like '%CASTS%'));
run;

Pour prendre toutes les observations indépendamment de la case ajouter la fonction UPCASE autour du nom de la variable UPCASE(TEST_LAB) like…

Un exemple avec le tiret bas : imaginons que vous vouliez repérer toutes les tests en rapport avec « Leukocyte esterase » mais vous envisagerez une mauvaise saisie au niveau du k, c et y. Vous demandez alors toutes les observations ressemblant au mot « Leukocyte esterase » en acceptant n’importe quelle autre valeur pour k, c et y.

data check_leuk;
   set lab (where=(test_lab like 'LEU_O__TE ESTERAS'));
run;

Un exemple combinant pourcentage et tiret bas : dans ce troisième et dernier exemple, on cherche à trouver toutes les observations contenant le mot CAST tout en assumant que la lettre A peut être erronnée dans les données du data set LAB. N’importe quel caractère à l’emplacement du A est autorisé.

data check_casts;
   set lab (where=(test_lab like '%C_ST%'));
run;

La même chose avec PROC SQL

proc sql;
   create table check_casts as
       select *
       from lab
       where test_lab like '%C_ST%';
quit;

Annexe : CASTS réfère à des tests de laboratoires sur les urines (urinal test).

data lab;
   length test_label $100;
   input test_label $;
   datalines;
FATTY CASTS
GRANULAR CASTS
HYALINE CASTS
RED BLOOD CELL COSTS
LEUKOCYTE ESTERASE
RENAL TUBULAR EPITHELIAL CASTS
WAXY CASTS
WHISTE BLOOD CELL CASTS
KETONE
;
run;
Suivre

Recevez les nouvelles publications par mail.

Rejoignez 56 autres abonnés