如何在 SAS 中对特定观察使用调用 symput

How to use call symput on a specific observation in SAS

我正在尝试将 SAS 数据集列转换为宏变量列表,但不确定索引在此语言中的工作方式。

    DATA _Null_;
       do I = 1 to &num_or;
       set CondensedOverrides4 nobs = num_or;
       call symputx("Item" !! left(put(I,8.))
       ,"Rule", "G");
    end;
    run;

现在这段代码创建了一个宏变量列表 Item1、Item2、..ItemN 等,并将名为 "Rule" 的整个列分配给每个新变量。我的目标是将 "Rule" 的第一个观察结果放在 Item1 中,将第二个观察结果放在 Item2 的该列中,依此类推。

我是 SAS 的新手,我知道你不能像其他语言一样强行逻辑,但如果有办法做到这一点,我将不胜感激。

SAS 不需要循环访问每一行,它会自动执行。所以你的代码真的很接近。使用自动变量 _n_ 代替 I,它可以用作行计数器,尽管它实际上是一个计步器。

DATA _Null_;
   set CondensedOverrides4;
   call symputx("Item" || put(_n_,8. -l) , Rule, "G");
run;

老实说,如果您是 SAS 新手,不建议您使用宏变量作为开始,通常有多种方法可以避免它,我只在别无选择时才使用它。它非常强大,但容易出错且更难调试。

编辑:我修改了代码以删除 LEFT() 函数,因为您可以在 PUT 语句中使用 -l 选项直接将结果左对齐。

EDIT2:删除 RULE 周围的引号,因为我怀疑它是您要存储其值的变量,而不是文本字符串 'RULE'。如果您希望宏变量解析为字符串,您可以加回引号,但根据您的问题,这似乎不正确。

使用 PROC SQLINTO 子句创建一系列宏变量要容易得多。您可以将项目的数量保存到一个宏变量中。

proc sql noprint;
  select rule into :Item1- 
  from CondensedOverrides4
  ;
%let num_or=&sqlobs;
quit;

如果您想使用数据步骤,则不需要 DO 循环。数据步骤自动迭代输入。将用于将观察次数保存到宏变量中的代码放在 set 语句之前,以防输入数据集为空。

data _null_;
  if eof then call symputx('num_or',_n_-1);
  set CondensedOverrides4 end=eof ;
  call symputx(cats('Item',_n_),rule,'g');
run;