Lorsque vous devez présenter vos données (faire du reporting), vous pouvez vous trouver dans la situation suivante : mettre côte-à-côte des données qui n’ont rien à voir entre elles. La situation peut se résoudre très rapidement avec un merge sans instruction BY. Mais que faire dans le cas où vous devez quand même grouper vos données par une clé (exemple l’identifiant du client) mais dans chaque source plus d’une observation par clé ? C’est ce que je vous propose de découvrir dans cet article.
1. Les données pour l’exemple
Deborah a deux lignes d’observation et Patrick aussi.
data demography;
length cl_name $10 criteria $10 ;
input cl_name $ criteria $ crit_value ;
datalines;
deborah age 15
deborah height 1.66
patrick age 14
patrick height 1.75
;
run;
Deborah a acheté 4 articles (DVD, téléphone portable, une radio et des écouteurs (4 lignes d’observations pour Deborah) tandis que Patrick a acheté deux articles.
data sell;
length cl_name $10 achat $10;
input cl_name $ achat $;
datalines;
deborah dvd
deborah mobile
deborah radio
deborah headset
patrick mobile
patrick tv
;
run;
2. Le résultat sans instruction BY
data mix_demo_sell;
merge demography
sell;
by cl_name;
run;
Vous vous retrouvez avec un merge MANY-to-MANY qui ne résous par votre problème. Pensez toujours à vérifer votre log après un MERGE. Ce type de note est souvent signe d’une erreur de raisonnement dans votre programme.
proc print data=mix_demo_sell;
run;
On observe ici un RETAIN implicite propre au merge.
3. Ajouter un compteur pour chaque client
Pour contourner le problème, on ajouter un identifiant supplémentaire dans les deux tables.
Dans la table DEMOGRAPHY, le client DEBORAH a deux observations. On aura donc CNT=1 et CNT=2.
data demography;
set demography;
by cl_name;
if first.cl_name then cnt=1;
else cnt+1;
run;
Dans la table SELL, le client DEBORAH a quatre observations. On aura donc CNT=1, CNT=2, CNT=3 et CNT=4.
data sell;
set sell;
by cl_name;
if first.cl_name then cnt=1;
else cnt+1;
run;
Il ne reste plus qu’à combiner les deux tables à partir de la variable client (CL_NAME) et de la variable CNT.
data mix_demo_sell;
merge demography
sell;
by cl_name cnt;
run;
proc print data=mix_demo_sell;
run;
Le résultat désiré se présente ainsi :
Lecture complémentaire