Pregunta

Estoy buscando una manera de crear una variable de cadena que contenga ciertos valores del conjunto de datos mientras pasa por el paso de datos.

Ejemplo del conjunto de datos Work.Test:

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

Entonces, al final, la variable se vería como: onetwoFour (o incluso mejor de FourTwoone). Esto se ve tan simple, pero parece que no puedo encontrar una manera de hacerlo. También intenté trabajar con variables macro como esta:

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

Pero esto da:

GLOBAL STRINGVAR Four

Así que solo obtengo el último valor. Entiendo que esto debe deberse a algunos malentendidos mía sobre esta instalación macro, pero no entiendo por qué solo existe el último valor en la variable. Pensé que era solo la última vez que se llamaba Symput que en realidad se ejecutó o algo así, pero cuando ajusto el código a:

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

Entonces los consigo a todos:

GLOBAL STRINGVARONE  One
GLOBAL STRINGVARTWO  Two
GLOBAL STRINGVARFOUR  Four

Entonces, mi última suposición es que al pasar por el paso de datos, la línea 'Call Symput ...' en realidad se agrega al procesador Macro donde el "& StringVar" ya está reemplazada y solo después de la declaración final se ejecutan.
¿Es esta una buena suposición o hay otra explicación? Y volver a la pregunta original: ¿Hay una manera fácil de lograr esto (tener la variable deseada)?

¿Fue útil?

Solución

Los saludos parecen bastante simples, aquí está mi solución:

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;

En este ejemplo, tiene la concatenación de su variable en el conjunto de datos A en la columna "Cat" y tiene un var macrovariable con la misma lista

Otros consejos

La siguiente es mi respuesta a Su pregunta idéntica en runsubmit.com. Creo que usted y @fabio pueden estar sobrepenitando la solución, no necesita ningún código de paso de datos iterando en absoluto ...

Primero, la manera fácil de hacer lo que estás tratando de hacer es así:

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

Aquí, puede aprovechar la interfaz SQL con SAS/Macro, utilizando el select into sintaxis. Incluso podrías agregar un order by Cláusula para obtener un pedido en particular que está buscando.

En segundo lugar, ya que ha encontrado algo sobre la forma en que funciona SAS Macro y está ansioso por comprenderlo: en su primer ejemplo, lo primero que hace el compilador antes de ejecutar su código es resolver el valor de &stringvar, que en ese punto está vacío. Entonces, después de la compilación, con este token reemplazado, su código se ve así a SAS ...

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

... Entonces SAS sigue adelante y ejecuta ese código (que resulta ser un código válido, pero está concatenando una cadena vacía al comienzo de algo). Y debido a la forma en que funciona el paso de datos, cada iteración del paso de datos está de hecho reemplazando el valor de StringVar, por eso al final del paso de datos, se queda con el último valor que se leyó.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top