Clause WHERE sous SAS

Sélectionnez vos observations avec la clause WHERE

A l'instar des instructions SQL, la clause WHERE sous SAS va nous permettre de sélectionner les observations d'une table en précisant un ou plusieurs critères. L'instruction WHERE va pouvoir être utilisée dans une étape DATA et dans la majorité des étapes PROC. Attention cependant, il n'est en effet possible de mentionner qu'une seule instruction WHERE, que ce soit dans une étape DATA ou PROC. Dans le cas contraire, seule la dernière instruction WHERE sera appliquée aux données.
Voyons plus en détails comment s'écrit une clause WHERE sous SAS.

Données de travail

Nous allons travailler avec une base des membres d'une salle de sport, ce set comporte 5 colonnes, à savoir l'identifiant du membre, son âge, son sexe (H ou F), son prénom ainsi que sa date d'inscription dans la salle. Le set compte 56 membres. Chargeons tout d'abord les données puis voyons à quoi elles ressemblent.


options validvarname=any;
filename FILE "/home/u49997643/gorenja/salle_sport.csv" 
         encoding='utf-8' ;

proc import datafile=FILE out=work.sport dbms=csv replace;
delimiter = ';';
getnames  = yes;
run;

proc print data=work.sport;
format inscription date9.;
run;
SAS where

Opérateurs de comparaison

Nous retrouvons les opérateurs de base, comme listés ci-dessous. A noter qu'il est possible d'employer aussi bien le symbole mathématique que la contraction. A noter également que deux symboles distincts sont possibles pour exprimer la négation. Par ailleurs un filtre plus complexe comme l'inclusion dans un ensemble ne pourra se faire que va la contraction IN.

SAS where operateur comparaison

Ci-dessous quelque exemple d'utilisation.


/*Edition des membres ages de 60 ans ou plus */
proc print data=work.sport;
where age GE 60;
run;

/*Edition des membres feminines uniquement */
proc print data=work.sport;
where sexe = 'F';
run;

/*Edition des membres inscrits avant le 1er janvier 2020  */
proc print data=work.sport;
where inscription < "01JAN2020"d;
format inscription date9.;
run;

/*Edition de certains membres dont le prenom commence par Jean  */
proc print data=work.sport;
where prenom IN ("Jean", "Jean-Baptiste", "Jean-Marie");
run;

Vous noterez que le dernier exemple est loin d'être efficace si l'objectif est d'afficher réellement tous les prénoms commençant par Jean. Nous reviendrons sur ce point.

Opérateurs logiques

Ci-dessous les opérateurs logiques tels que SAS peut les interpréter. Nous avons déjà précisé qu'une seule instruction WHERE n'est autorisée par étape, les opérateurs logiques vont donc nous aider à étendre le spectre d'application des filtres.
Il faut préciser enfin que les parenthèses nous serviront à dicter les priorités.

SAS where operateur logique

/*Exemple de selection multiple  */
proc print data=work.sport;
WHERE (age = 59 | age = 60) & sexe = "F" & inscription >= "01JAN2020"d;
FORMAT inscription date9.;
run;

Opérateurs spéciaux

Nous terminons par les opérateurs spéciaux, ainsi nommés car ils sont issus d'une mécanique sous-jacente plus complexe. Ci-dessous les opérateurs que nous allons détailler un par un.

SAS where operateur reserves speciaux contains like between same also null missing

Opérateur CONTAINS

Il s'agit ici de déterminer si une sous-chaine donnée est incluses dans une chaine de caractères, quelle que soit sa position. Cet opérateur est sensible à la casse. Par ailleurs, CONTAINS peut également être appelé via l'abréviation ?, ainsi les deux exemples ci-dessous vont donner le même résultat :


/*Tous les membres dont le prenom contient 'Marie' */
proc print data=work.sport;
where prenom ? 'Marie';
run;

proc print data=work.sport;
where prenom contains 'Marie';
run;

Opérateur LIKE

L'opérateur LIKE va chercher tous les enregistrements dont la valeur du champs requeté répond au masque (ou pattern) indiqué. Pour rappel, nous avions dans un précèdent exemple cherche à éditer les membres dont le prénom commence par Jean. Avec LIKE il nous suffira de faire ceci :


proc print data=work.sport;
where prenom like 'Jean%';
run;

Vous noterez le caractère % qui vous nous permettre d'indiquer à SAS qu'un ou plusieurs caractères suivent. Si nous voulons lui signifier qu'un caractère exactement doit être pris en compte, le caractère _ sera utilisé.
Ainsi, si vous voulons tous les membres dont la seconde lettre du prénom est un e, l'instruction WHERE va ressembler à ceci :


proc print data=work.sport;
where prenom like '_e%';
run;

Opérateur BETWEEN-AND

L'opérateur BETWEEN-AND est assez intuitif dans son utilisation, il va nous permettre de sélectionner des enregistrements dont la valeur du champs requêté est comprise entre 2 bornes. Ces bornes sont incluses dans la sélection. Par ailleurs cet opérateur s'applique aussi bien aux valeurs numériques que caractères.


/*Tous les membres dont l'age est compris entre 40 et 50 ans */
proc print data=work.sport;
where age between 40 and 50;
run;

/*Tous les membres dont le prenom commence par A, B ou est egal a C */
proc print data=work.sport;
where prenom between 'A' and 'C';
run;

/*Tous les membres dont l'inscription est comprise entre
  le 01 Juin 2020 et le 31 aout 2020 */
proc print data=work.sport;
where inscription between '01JUN2020'd and '31AUG2020'd;
format inscription date9.;
run;

Dans le cas d'un bornage sur une chaine de caractères, comme illustré dans le second exemple ci-dessus, il convient de faire attention à deux choses. D'une part l'opérateur est sensible à la casse, et d'autre part, la borne supérieure peut prêter a confusion. Dans notre exemple, vont ressortir les prénoms valant ou commençant par A, les prénoms valant ou commençant par B ainsi que les prénoms valant C. Les prénoms commençant par C ne seront en effet pas inclus car en dehors de la plage.

Opérateur WHERE ALSO / WHERE SAME AND

Nous avons précisé en débutant l'article qu'un seul WHERE n'était autorisé par étape. Ainsi, lister plusieurs WHERE de suite aboutira à la prise en compte du dernier uniquement. Les opérateurs logiques, dont nous avons déjà parlés, peuvent nous aider à procéder a une sélection multiple, et c'est d'ailleurs la solution à privilégier. Néanmoins, une autre solution s'offre à nous. Il s'agit d'unir plusieurs clauses WHERE via les instructions WHERE SAME et WHERE ALSO. On parle alors d'augmentation. Cette solution peut s'avérer utile pour conserver un code lisible.
Concrètement chaque instruction WHERE ALSO va augmenter l'instruction précédente de filtres supplémentaires. Il faut donc considérer un "et" logique entre chaque. L'instruction WHERE SAME AND constitue la même instruction, celle-ci est néanmoins plus compréhensible peut-être dans la mesure ou le terme AND apparait clairement.


/* femme de 65 ans dont le prenom contient 'Louise' */
proc print data=work.sport;
where sexe='F';
where also age = 65;
where also prenom contains 'Louise';
run;

Opérateur IS NULL / IS MISSING

Les opérateurs IS NULL et IS MISSING sélectionnent tous deux les enregistrements dont la valeur du champs requêté est manquante. Pour le type chaine, une donnée manquante aura pour valeur '', pour les types numériques une donnée manquante aura pour valeur . (le point). On peut donc considérer que IS NULL ou IS MISSING sont les équivalents de var_num = . ou var_car = ''
Enfin, précision que les sélections inverses, toutes aussi utiles, sinon plus, s'écriront IS NOT NULL et IS NOT MISSING.


/* Observations dont le sexe est bien renseigne */
proc print data=work.sport;
where sexe is not missing;
run;

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