logo

Macro : Éliminer les valeurs d’une liste1 existantes dans une liste2

Bonjour,

J’ai 2 listes de variables liste1 et liste2 (2 macro variables)

<strong>%let liste1= a b c ;</strong>
<strong>%let liste2=(a f d) ;</strong>
<strong>%let liste3=; </strong>

Je souhaite comparer chaque variable de la liste1 avec toutes les variables de la liste2 pour constituer une liste3 excluant de la liste1 les variables figurant dans la liste2 (soit liste3=b c);

Ci après le code que j’ai écris

<strong>%do i=1 %to &amp;n;</strong>
<strong>    %if %scan(&amp;liste1,&amp;i) not in &amp;liste2 %then %do;</strong>
<strong>       %let liste3=liste3 %scan(&amp;liste1,&amp;i);</strong>
<strong>    %end;</strong>
<strong>%end; </strong>

NB : n est le nombre d’éléments de la liste1 que j’ai précédemment récupéré.

Le pb c’est que ça ne marche pas et ci-après la log :

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: %scan(&liste1,&i) not in &liste2

Je ne comprends pas cette erreur. Merci d’avance de votre aide.

Bonjour.

Le problème, c’est qu’avant la version 9 de SAS, l’opérateur IN n’existe pas en macro-langage. Il le prend donc pour du texte et n’arrive pas à évaluer la condition.
Par contre, on peut utiliser une fonction comme TRANWRD, qui va remplacer un nom de variable vu dans LISTE2 par un blanc. Après avoir passé tout LISTE2 en revue (TRANWRD n’accepte qu’un mot à la fois à remplacer), on supprime les blancs inutiles pour la beauté du résultat.

%let liste1= a b c ;
 %let liste2= a f d ;
 %let liste3=;
 %MACRO sansListe2 ;
    %GLOBAL liste3 ;
    %LET liste3 = &amp;liste1 ;
    %LET i = 1 ;
    %DO %WHILE (%SCAN(&amp;liste2,&amp;i) NE ) ;
       %LET liste1 = %SYSFUNC(TRANWRD(&amp;liste1,%SCAN(&amp;liste2,&amp;i), )) ;
       %LET i = %EVAL(&amp;i + 1) ;
    %END ;
    %LET liste3 = %SYSFUNC(COMPBL(&amp;liste3)) ;
 %MEND sansListe2 ;
 %sansListe2 ;