2

我正在寻找一种在执行数据步骤时创建包含数据集某些值的字符串变量的方法。

示例数据集 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

所以我只得到最后一个值。我知道这一定是因为我对这个宏工具有一些误解,但我不明白为什么变量中只有最后一个值。我以为只有最后一次调用 symput 才实际执行了它或其他什么,但是当我将代码调整为:

%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" 已经被替换,并且只有在最后的语句之后它们才会全部执行。
这是一个很好的假设还是有其他解释?回到最初的问题:有没有一种简单的方法可以实现这一点(具有所需的变量)?

4

2 回答 2

5

以下是我在 RunSubmit.com 上对您的相同问题的回答。我认为您和@Fabio 可能过度设计了解决方案,它根本不需要任何迭代数据步骤代码......

首先,做你想做的事情的简单方法是这样的:

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

在这里,您可以利用 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;

...然后 SAS 继续运行该代码(这恰好是有效代码,但将一个空字符串连接到某事的开头)。而且由于数据步骤的工作方式,数据步骤的每次迭代实际上都在替换 的值StringVar,这就是为什么在数据步骤结束时,它会保留最后一个读入的值。

于 2011-04-29T15:09:06.667 回答
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

于 2011-04-29T10:45:06.270 回答