САС переменная конкатенация через шаг данных
Вопрос
Я ищу способ создания строковой переменной, содержащей определенные значения набора данных при прохождении шага данных.
Пример набора данных Work.test:
AddToStringYN Value
Y One
Y Two
N Three
Y Four
N Five
Таким образом, в конце концов, переменная будет выглядеть как: OneTwofour (или даже лучший Fourtwone). Это выглядит так просто, но я не могу найти способ сделать это. Я также пытался работать с макро -переменными, как это:
%let stringvar=;
Data _null_;
set work.test;
if AddToStringYN = "Y" then do;
call symput('stringvar',"&stringvar" || strip(value));
end;
Run;
Но это дает:
GLOBAL STRINGVAR Four
Так что я получаю только последнее значение. Я понимаю, что это должно быть из -за моего недопонимания в этом макросмерке, но я не понимаю, почему в переменной есть только последнее значение. Я думал, что это был только в последний раз, когда симпт назывался, что он был фактически выполнен или что -то в этом роде, но затем, когда я настраиваю код на:
%let stringvar=;
Data _null_;
set work.test;
if AddToStringYN = "Y" then do;
call symput('stringvar'||strip(value),"&stringvar" || strip(value));
end;
Run;
Тогда я получаю их все:
GLOBAL STRINGVARONE One
GLOBAL STRINGVARTWO Two
GLOBAL STRINGVARFOUR Four
Поэтому я предполагаю, что прохождение шага данных, строка «Симпут вызовов ...» фактически добавляется в макропроцессор, где «& stringvar» уже заменена, и только после окончательного утверждения все они выполнены.
Это хорошее предположение или есть еще одно объяснение? И вернемся к первоначальному вопросу: есть ли простой способ достичь этого (имея желаемую переменную)?
Решение
Приветствия кажется достаточно простым, вот мое решение:
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;
В этом примере у вас есть объединение вашей переменной в наборе данных A в столбце «Cat», и у вас есть макровариный VAR с одним и тем же списком
Другие советы
Ниже приведен мой ответ на Ваш идентичный вопрос на runsubmit.com. Анкет Я думаю, что вы и @fabio, возможно, переживаете решение, он вообще не нуждается в коде шага итерации данных ...
Во -первых, простой способ сделать то, что вы пытаетесь сделать, это так:
proc sql;
select Value into :StringVar separated by ''
from work.test
where AddToStringYN='Y'
;
quit;
Здесь вы можете воспользоваться интерфейсом SQL с SAS/Macro, используя select into
синтаксис. Вы даже можете добавить order by
Пункт, чтобы получить конкретный заказ, который вы ищете.
Во -вторых, так как вы столкнулись с чем -то о том, как работает макросы SAS, и вы заинтересованы в этом: в своем первом примере первое, что делает компилятор до выполнения вашего кода, это разрешить значение значения &stringvar
, что в этот момент пуст. Итак, после компиляции, с заменой токена, ваш код выглядит так для SAS ...
%let stringvar=;
Data _null_;
set work.test;
if AddToStringYN = "Y" then do;
call symput('stringvar',"" || strip(value));
end;
Run;
... Затем SAS идет вперед и запускает этот код (который является действительным кодом, но объединяет пустую строку к началу чего -либо). И из -за того, как работает шаг данных, каждая итерация шага данных фактически заменяет значение StringVar
, вот почему в конце шага данных осталось с последним значением, которое было прочитано.