Yoh*_*Yoh 2 variables sas datastep sas-macro
我正在寻找一种方法来创建一个包含数据集的某些值的字符串变量,同时通过数据步骤.
示例数据集work.test:
AddToStringYN Value
Y One
Y Two
N Three
Y Four
N Five
Run Code Online (Sandbox Code Playgroud)
所以最后,变量看起来像:OneTwoFour(甚至更好的FourTwoOne).这看起来很简单,但我似乎无法找到办法.我也尝试使用像这样的宏变量:
%let stringvar=;
Data _null_;
set work.test;
if AddToStringYN = "Y" then do;
call symput('stringvar',"&stringvar" || strip(value));
end;
Run;
Run Code Online (Sandbox Code Playgroud)
但这给了:
GLOBAL STRINGVAR Four
Run Code Online (Sandbox Code Playgroud)
所以我只得到最后一个值.我知道这一定是因为我对这个宏设施有一些误解,但我不明白为什么变量中只有最后一个值.我认为这只是最后一次调用它的实际执行或其他东西,但是当我调整代码时:
%let stringvar=;
Data _null_;
set work.test;
if AddToStringYN = "Y" then do;
call symput('stringvar'||strip(value),"&stringvar" || strip(value));
end;
Run;
Run Code Online (Sandbox Code Playgroud)
然后我确实得到了所有这些:
GLOBAL STRINGVARONE One
GLOBAL STRINGVARTWO Two
GLOBAL STRINGVARFOUR Four
Run Code Online (Sandbox Code Playgroud)
所以我的最后一个猜测是,通过数据步骤,'call symput ...'行实际上被添加到宏处理器中,其中"&stringvar"已经被替换,并且只有在最终语句之后它们全部被执行.
这是一个很好的假设还是有另一种解释?回到最初的问题:是否有一种简单的方法来实现这一目标(拥有所需的变量)?
以下是我对RunSubmit.com上相同问题的回答.我认为你和@Fabio可能会过度设计解决方案,它根本不需要任何迭代数据步骤代码......
首先,做你想做的事的简单方法是这样的:
proc sql;
select Value into :StringVar separated by ''
from work.test
where AddToStringYN='Y'
;
quit;
Run Code Online (Sandbox Code Playgroud)
在这里,您可以使用SAS/MACRO的SQL接口,使用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;
Run Code Online (Sandbox Code Playgroud)
...然后SAS继续运行该代码(恰好是有效代码,但是将空字符串连接到某些东西的开头).并且由于数据步骤的工作方式,数据步骤的每次迭代实际上都替换了值StringVar,这就是为什么在数据步骤结束时,它留下了读入的最后一个值.