通过数据步骤进行SAS变量连接

时间:2011-04-29 10:06:06

标签: variables sas sas-macro datastep

我正在寻找一种方法来创建一个包含数据集某些值的字符串变量,同时完成数据步骤。

示例数据集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”已被替换,并且只有在最终语句之后它们全部执行。
这是一个很好的假设还是有另一种解释? 回到最初的问题:是否有一种简单的方法可以实现这一目标(拥有所需的变量)?

2 个答案:

答案 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