我正在寻找一种方法来创建一个包含数据集某些值的字符串变量,同时完成数据步骤。
示例数据集work.test:
AddToStringYN Value
Y One
Y Two
N Three
Y Four
N Five
所以最后,变量看起来像:OneTwoFour(甚至更好的FourTwoOne)。 这看起来很简单,但我似乎无法找到办法。 我也尝试使用像这样的宏变量:
%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
所以我的最后一个猜测是,通过数据步骤,'call symput ...'行实际上被添加到宏处理器中,其中“& stringvar”已被替换,并且只有在最终语句之后它们全部执行。
这是一个很好的假设还是有另一种解释?
回到最初的问题:是否有一种简单的方法可以实现这一目标(拥有所需的变量)?
答案 0 :(得分:5)
以下是我对your identical question on RunSubmit.com的回答。我认为你和@Fabio可能会过度设计解决方案,它根本不需要任何迭代数据步骤代码......
首先,做你想做的事的简单方法就是这样:
proc sql;
select Value into :StringVar separated by ''
from work.test
where AddToStringYN='Y'
;
quit;
在这里,您可以使用select into
语法,利用SAS / MACRO的SQL接口。您甚至可以添加order by
子句来获取您正在寻找的特定订单。
其次,既然你已经发生了关于SAS宏的工作方式并且你很想理解它的事情:在你的第一个例子中,编译器在执行代码之前做的第一件事是解析{{{ 1}},此时为空。所以在编译之后,替换了这个标记,你的代码看起来就像SAS ......
&stringvar
...然后SAS继续运行该代码(恰好是有效的代码,但是将空字符串连接到某些东西的开头)。并且由于数据步骤的工作方式,数据步骤的每次迭代实际上都替换了%let stringvar=;
Data _null_;
set work.test;
if AddToStringYN = "Y" then do;
call symput('stringvar',"" || strip(value));
end;
Run;
的值,这就是为什么在数据步骤结束时,它留下了读入的最后一个值
答案 1 :(得分:2)
问候 看起来很简单,这是我的解决方案:
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;
在此示例中,您在“CAT”列中的A数据集中具有变量的串联,并且您具有具有相同列表的宏变量VAR