Posts Tagged ‘many-to-many’

h1

Savoir interpréter une note liée au MERGE

juin 5, 2008

Dans un cas particulier, une jointure many-to-many avec un MERGE, SAS génère une note. Il est très important de savoir l’interpréter. En effet, il est fréquent de vouloir un FULL JOIN (PROC SQL) mais d’utiliser maladroitement le MERGE (Data Step). Je vous propose donc de voir la différence entre les deux approches.

Rappel : si dans chacun des deux data sets à fusionner, il y a des doublons pour les variables communes, il s’agit d’une jointure MANY-TO-MANY.

Données utilisées pour illustrer le sujet : voici deux data sets appelés FRST_MANY et SECOND_MANY avec chacun trois variables. Les variables X et Y sont présentes dans les deux data sets. Dans le premier data set, trois lignes d’observations ont pour valeur x=A, y=B. Dans le second data set, deux lignes d’observations ont pour valeurs x=A, y=B et deux autres x=B, y=D.

 frst_many       second_many
 a    x    y     x    y    b
 1    A    B     B    D    2
 2    A    B     B    D    8
 9    A    B     A    B    4
 3    C    D     A    B    3
 5    B    D     E    F    6

1. Premier Choix, le FULL JOIN de la PROC SQL : on veut que chaque ligne d’observations de FRST_MANY soit dupliquée s’il y a plusieurs lignes d’observations dans SECOND_MANY ayant les mêmes BY variables ; et inversement.

En d’autres termes, vu que x=A, y=B apparaît trois fois dans le premier data set et deux fois dans le second, il y aura six lignes d’observations après la fusion des jeux de données.

De même, vu qu’il y a une observation x=B, y=D dans le premier jeu et deux dans le second jeux, il y aura deux observations après la fusion et la variable a=5 du premier jeux sera dupliquée pour chaque ligne.

      final
 a    x    y    b
 1    A    B    3
 2    A    B    3
 9    A    B    3
 1    A    B    4
 2    A    B    4
 9    A    B    4
 5    B    D    2
 5    B    D    8
 3    C    D    .
 .    E    F    6

En terme de programmation SAS, cela donne :

proc sql;
   create table final as
   select a,
          coalesce(one.x,two.x) as x,
          coalesce(one.y,two.y) as y,
          b
   from   frst_many one
   full join
          second_many two
   on     one.x=two.x and
          one.y=two.y;
quit;

2. Second Choix, MERGE : pour chaque combinaison de BY variables, le nombre de lignes dans le data set final correspond au nombre de ligne le plus important parmi les deux data sets d’origine.

Dans ce cas, SAS génère la note suivante, très importante :

NOTE: MERGE statement has more than one data set with repeats of BY values.

Le mieux est encore de regarder l’exemple pour comprendre ce qui se passe.

Vu qu’il y a trois lignes d’observations pour x=A, y=B dans le premier jeu, et seulement deux dans le second, il y aura trois lignes d’observations au final pour ces BY variables. La deuxième et dernière valeur de la variable b du second data set (b=3) sera dupliquée pour les lignes supplémentaires.

Vu qu’il y a deux lignes d’observations pour x=B, y=D dans le second jeu et une seule dans le premier, la valeur de la variable a du premier data set (a=5) sera également dupliquée pour la ligne supplémentaire.

      final
 a    x    y    b
 1    A    B    4
 2    A    B    3
 9    A    B    3
 5    B    D    2
 5    B    D    8
 3    C    D    .
 .    E    F    6

Pour obtenir ce résultat, il faut passer par un MERGe et si besoin trier les données :

proc sort data=frst_many;
   by x y;
run;

proc sort data=second_many;
   by x y;
run;

data final;
   merge frst_many
         second_many;
   by x y;
run;

 

Annexe : syntaxe pour créer les data sets et ainsi tester la PROC SQL et le MERGE.


data frst_many;
   input a x $ y $;
   datalines;
1 A B
2 A B
9 A B
3 C D
5 B D
;
run;

 

data second_many;
   input x $ y $ b;
   datalines;
B D 2
B D 8
A B 4
A B 3
E F 6
;
run;