Question

Je cherche un moyen de créer une variable de chaîne contenant certaines valeurs de l'ensemble de données en passant par l'étape de données.

Exemple ensemble de données work.test:

AddToStringYN    Value
     Y           One
     Y           Two
     N           Three
     Y           Four
     N           Five

Donc à la fin, la variable ressemblerait à ceci: OneTwoFour (ou mieux encore FourTwoOne). Cela semble si simple, mais je ne peux pas sembler trouver une façon de le faire. J'ai essayé aussi de travailler avec des variables macro comme ceci:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"&stringvar" || strip(value));
  end;
Run;

Mais cela donne:

GLOBAL STRINGVAR Four

Je ne reçois que la dernière valeur. Je reçois que ce doit être à cause d'un malentendu à moi au sujet de cette installation macro, mais je ne comprends pas pourquoi il n'y a que la dernière valeur de la variable. Je pensais que ce n'était que la dernière fois que le symput a été appelé qu'il a été effectivement exécuté ou quelque chose, mais quand je règle le code:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar'||strip(value),"&stringvar" || strip(value));
  end;
Run;

Alors j'obtenir tous:

GLOBAL STRINGVARONE  One
GLOBAL STRINGVARTWO  Two
GLOBAL STRINGVARFOUR  Four

Donc, ma dernière supposition est que passer par l'étape de données, la ligne « symput d'appel ... » est en fait ajouté au processeur macro où le « & stringvar » est déjà remplacé et seulement après la déclaration finale sont tous exécutés.
Est-ce une bonne hypothèse ou est-il une autre explication? Et revenir à la question initiale: est-il un moyen facile d'y parvenir (ayant la variable souhaitée)

Était-ce utile?

La solution

Salutations Il semble assez simple, voici ma solution:

data a;
set test end=eof;
length cat $100.;
retain cat;
if AddToStringYN = "Y" then do;
   cat=trim(left(cat))||trim(left(value));
end;
if eof then do;
   call symput("VAR",cat);
   output;
end;
run;

%put VAR=&VAR;

Dans cet exemple, vous avez la concaténation de votre variable dans l'ensemble de données A dans la colonne « CAT » et vous avez un macrovariable VAR avec la même liste

Autres conseils

Voici ma réponse à votre question identique sur RunSubmit.com . Je pense que vous et peut-être plus @Fabio-ingénierie de la solution, il n'a pas besoin de code étape de données itérer du tout ...

Tout d'abord, la manière facile de faire ce que vous essayez de faire est comme ceci:

proc sql;
  select Value into :StringVar separated by ''
    from work.test
    where AddToStringYN='Y'
    ;
quit;

Ici, vous pouvez profiter de l'interface SQL avec SAS / MACRO, en utilisant la syntaxe select into. Vous pouvez même ajouter une clause de order by pour obtenir un ordre particulier que vous recherchez.

En second lieu, puisque vous avez tombé sur quelque chose sur la façon dont SAS macro fonctionne et vous êtes désireux de le comprendre: dans votre premier exemple, la première chose que le compilateur fait avant d'exécuter votre code est de résoudre la valeur de &stringvar, qui à ce moment est vide. Ainsi, après la compilation, avec ce jeton remplacé, votre apparence de code comme celui-ci à SAS ...

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"" || strip(value));
  end;
Run;

... puis SAS va de l'avant et exécute ce code (qui se trouve être un code valide, mais est concaténer une chaîne vide au début de quelque chose). Et à cause de la façon dont les travaux de l'étape de données, chaque itération de l'étape de données est en fait de remplacer la valeur de StringVar, ce qui explique pourquoi à la fin de l'étape de données, il est laissé à la dernière valeur lue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top