Condition sur agrégat sous SAS

Utilisez le compteur d'itérations SAS à votre avantage pour calculer vos agrégats et les exploiter dans vos conditions

Disons que vous voulez, par exemple, extraire d'une table des commandes celles dont les délais de livraison sont supérieurs au 90eme percentile. Simple en apparence, cette requête s'avère en réalité plus complexe qu'elle n'y parait. Elle fait intervenir, en effet, un calcul de niveau ligne (le délai de livraison), une mesure agrégée sur le résultat du calcul précèdent (le 90eme percentile) et enfin une sélection des observations.
Voyons une solution possible pour implémenter cette requête.

Présentation des données

Pour illustrer nos propos, nous allons travailler avec un jeu de données regroupant 168 en-têtes de commandes. Ce dataset est disponible sur Gorenja.com ici.
Pour chaque commande nous disposons notamment des dates de commande, d'expédition et de livraison. Chargeons les données et visualisons un extrait :


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

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

proc print data=work.orders;
format date_commande date_expedition date_livraison ddmmyy10.;
run;
SAS agregat _n_ iteration condition format proc mean intck

Nous allons de suite définir le délai de livraison comme étant le nombre de jours qu'il s'est écoulé entre la date de commande et la date de livraison. Ceci étant dit, passons à l'implémentation d'une solution possible.

Agrégat sur colonne

Nous allons tout d'abord nous charger d'implémenter le calcul du 90e percentile. Pour cela nous allons constituer une table des délais de livraison puis, via une proc mean, en générer une seconde qui ne contiendra que la statistique en question :


/*Creation d'une table intermediaire des delais de livraions (en jours)*/
data delais_livraison (keep= date_commande date_livraison Diff);
set work.orders;
Diff = intck('day', date_commande, date_livraison);
run;

/*Calcul du 90e percentile a partir de la table precedente
  la sortie est dirigee vers une nouvelle table diff90*/
proc means data=delais_livraison noprint;
var Diff;
output out=diff90 p90=p90;
run;

Pour l'instant, nous n'avons rien fait de nouveau. Nous nous retrouvons avec une table diff90 dont le contenu ressemble à ceci :

SAS agregat _n_ iteration condition format proc mean intck

Nous constatons que la variable p90 contient 11, ce qui correspond au 90e percentile des délais de livraison observés sur l'échantillon de 168 commandes.

Compteur d'itérations

L'étape data que nous allons désormais implémenter pour sélectionner nos commandes va itérer sur les observations. Or nous ne voulons pas qu'un agrégat soit recalculé ou requêté à chaque itération. C'est pourquoi nous allons utiliser le compteur d'itérations _n_ (ou _N_) afin de requêter notre agrégat une seule fois, lors de la première itération. Voyons cela :


/*Selection des commandes*/
data livraison_lente;

/*A la premiere iteration on charge dans le PDV la seule ligne de la table diff90*/
if _n_ eq 1 then set diff90;

set work.orders;

/*Delai de livraison*/
Diff = intck('day', date_commande, date_livraison);

/*On redirige les commandes lentes vers une table de sortie*/
if (Diff >= p90) then output livraison_lente;
run;

Voyons le résultat :


proc print data=livraison_lente;
format date_commande date_expedition date_livraison ddmmyy10.;
run;
SAS agregat _n_ iteration condition format proc mean intck

25 commandes lentes, dont les délais de livraisons dépassent 11 jours, ont été retenues.


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