2015-05-07 11 views
5

Voglio creare qualcosa in SAS che funzioni come una funzione di ricerca Excel. Fondamentalmente, ho impostato i valori per le variabili macro var1, var2, ... e voglio trovare il loro numero di indice in base alla tabella ref. Ma ottengo i seguenti messaggi nel passaggio dei dati.non è inizializzata dopo l'istruzione% let in sas

NOTE: Variable A is uninitialized. 
NOTE: Variable B is uninitialized. 
NOTE: Variable NULL is uninitialized. 

Quando stampo le variabili &num1, &num2, non ottengo niente. Ecco il mio codice.

data ref; 
    input index varname $; 
    datalines; 
0 NULL 
1 A 
2 B 
3 C 
; 
run; 

%let var1=A; 
%let var2=B; 
%let var3=NULL; 

data temp; 
    set ref; 
    if varname=&var1 then call symput('num1',trim(left(index))); 
    if varname=&var2 then call symput('num2',trim(left(index))); 
    if varname=&var3 then call symput('num3',trim(left(index))); 
run; 

%put &num1; 
%put &num2; 
%put &num3; 

posso ottenere i valori corretti per &num1, &num2, .. se digito varname='A' nella dichiarazione if-then. E se in seguito cambio la frase in varname=&var1, posso ancora ottenere l'output richiesto. Ma perché è così? Non voglio inserire il valore effettivo della stringa e quindi riportarlo alla variabile macro per ottenere il risultato ogni volta.

+1

Io suggerirei di fare una ricerca su http://www.lexjansen.com/ per "ricerca" per trovare documenti SAS sui molti modi diversi di fare questo genere di cose in SAS. – DWal

risposta

8

Soluzione al problema immediato

È necessario avvolgere le variabili macro tra virgolette, se si desidera SAS a trattarli come costanti di stringa. Altrimenti, li tratterà allo stesso modo di qualsiasi altro pezzo di testo casuale trovato nel tuo passo di dati.

In alternativa, è possibile ridefinire le macro vars per includere le virgolette.

Come ulteriore opzione, è possibile utilizzare le funzioni symget o resolve, ma di solito non sono necessarie a meno che non si desideri creare una variabile macro e utilizzarla di nuovo all'interno dello stesso passaggio di dati. Se li si utilizza in sostituzione delle virgolette, tendono ad utilizzare molta più CPU, in quanto valuteranno le macro macro una volta per riga per impostazione predefinita: normalmente, le macro vars sono valutate solo una volta, in fase di compilazione, prima dell'esecuzione del codice.

Un approccio migliore?

Per il tipo di ricerca che si sta facendo, in realtà non è necessario utilizzare un set di dati del tutto - è possibile invece definire un formato personalizzato, che offre molta più flessibilità nel modo in cui è possibile utilizzarlo. Per esempio. questo crea un formato chiamato lookup:

proc format; 
    value lookup 
    1 = 'A' 
    2 = 'B' 
    3 = 'C' 
    other = '#N/A' /*Since this is what vlookup would do :) */ 
    ; 
run; 

Quindi è possibile utilizzare il formato in questo modo:

%let testvar = 1; 
%let testvar_lookup = %sysfunc(putn(&testvar, lookup.)); 

O in un passaggio di dati:

data _null_; 
    var1 = 1; 
    format var1 lookup.; 
    put var1=; 
run; 
+0

Vedo. Grazie per aver introdotto l'alternativa! – Yimai

+2

Buona risposta. Potresti anche voler spiegare come creare un formato da un set di dati qui (dato che l'utente potrebbe già avere questa ricerca in un set di dati). – Joe