Domanda

Sto cercando un modo per creare una variabile stringa contenente alcuni valori del set di dati mentre passa attraverso il passaggio di dati.

Esempio insieme di dati work.test:

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

Così, alla fine, la variabile sarà simile: OneTwoFour (o meglio ancora FourTwoOne). Questo sembra così semplice, ma non posso sembrare trovare un modo per farlo. Ho anche provato a lavorare con le variabili macro in questo modo:

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

Ma questo dà:

GLOBAL STRINGVAR Four

Quindi ho solo l'ultimo valore. Ottengo che questo deve essere causa di qualche incomprensione di mine su questa macro struttura, ma non capisco il motivo per cui v'è solo l'ultimo valore nella variabile. Ho pensato che fosse solo l'ultima volta che lo symput è stato chiamato, che in realtà è stato eseguito o qualcosa del genere, ma poi quando ho regolare il codice per:

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

Poi io capisco tutti:

GLOBAL STRINGVARONE  One
GLOBAL STRINGVARTWO  Two
GLOBAL STRINGVARFOUR  Four

Quindi la mia ultima ipotesi è che passare attraverso il passaggio di dati, il 'symput chiamata ...' linea è effettivamente aggiunto al processore macro in cui la "& stringvar" è già sostituito e solo dopo la dichiarazione finale sono tutti eseguiti.
Questo è un buon presupposto o c'è un'altra spiegazione? E torna alla domanda iniziale: c'è un modo semplice per raggiungere questo obiettivo (avendo la variabile desiderata)

È stato utile?

Soluzione

Saluti Sembra abbastanza semplice, qui è la mia soluzione:

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;

In questo esempio si ha la concatenazione della variabile in un set di dati nella colonna "CAT" e si dispone di un VAR macrovariable con la stessa lista

Altri suggerimenti

Di seguito è la mia risposta a tua domanda identica su RunSubmit.com . Penso che tu e @Fabio può essere over-engineering della soluzione, non ha bisogno di alcun codice passo dati iterazione a tutti ...

In primo luogo, il modo più semplice per fare quello che stai cercando di fare è come questo:

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

Qui, si può sfruttare l'interfaccia SQL con SAS / MACRO, utilizzando la sintassi select into. Si potrebbe anche aggiungere una clausola order by per ottenere un ordine particolare che stai cercando.

In secondo luogo, dal momento che hai capitato su qualcosa nel modo in cui SAS macro funziona e siete interessati a capire: nel primo esempio, la prima cosa che fa il compilatore prima di eseguire il codice è di risolvere il valore di &stringvar, che a quel punto è vuoto. Così, dopo la compilazione, con questo token sostituito, il tuo aspetto di codice come questo per SAS ...

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

... poi SAS va avanti e viene eseguito il codice (che risulta essere codice valido, ma si concatenazione una stringa vuota per l'inizio di qualcosa). E a causa del modo in cui funziona passo di dati, ogni iterazione del passaggio dei dati è di fatto sostituendo il valore di StringVar, che è il motivo per cui alla fine della fase dei dati, è lasciato con l'ultimo valore che è stato letto in.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top