【问题标题】:SAS using an iterating variable with a do loopSAS使用带有do循环的迭代变量
【发布时间】:2019-10-22 20:10:01
【问题描述】:

我有一个示例数据集,我正在尝试使用 do 循环从每个观察(记录)创建一个新数据集。

这是示例代码:

data tst;
input a b;
datalines;
1 2
2 3
;
run;

data ds1 ds2;
set tst 
/*point = point nobs = Nobs*/
;
do i=1 to 2;
    call symput("i",i);
    %put &=i;
    if _n_ then output ds&i.;
end;
run;

我很困惑为什么 &i. 没有正确解析。看起来在日志中前面有很多空间。我尝试在ds&i. 上使用压缩功能,但它不起作用。我知道我可以使用宏并在不调用 symput() 的情况下执行此操作,但我想知道这是什么问题?

理想输出:

DS1:
a b 1 2

DS2:
a b 2 3

【问题讨论】:

标签: loops sas do-loops


【解决方案1】:

这是一种已知行为。调用符号手册摘录:

在 SYMPUT 分配的值可用之前尝试引用它时出现问题

使用 SYMPUT 时最常见的问题之一是试图在创建该变量之前引用由 SYMPUT 分配的宏变量值。失败通常是因为引用宏变量的语句在执行分配变量值的 CALL SYMPUT 语句之前编译。使用 SYMPUT 时要记住的最重要的事实是它在程序执行期间分配宏变量的值。宏变量引用在编译步、步外使用的全局语句或 SCL 程序期间解析。结果:

您不能在 SYMPUT 创建宏变量并为其分配值的同一程序(或步骤)中使用宏变量引用来检索宏变量的值。

在引用程序后面的全局语句(例如,TITLE 语句)中的值之前,您必须指定步边界语句以强制执行 DATA 步。边界可以是 RUN 语句或另一个 DATA 或 PROC 语句。

【讨论】:

  • 使用 SYMGET() 在同一数据步骤中使用变量。这已更新。
【解决方案2】:

它发生的原因是宏变量不能在初始化它的数据步骤中使用。所以我认为你应该使用宏(并修复 if 语句,在我认为应该完成的示例中):

data tst;
input a b;
datalines;
1 2
2 3
;
run;

%macro output(); %macro d;%mend d;
   data ds1 ds2;
   set tst 
   /*point = point nobs = Nobs*/
   ;
   %do i=1 %to 2;
       if mod(_n_,&i)=0 then output ds&i.;
       /*if _n_=&i then output ds&i.;*/
   %end;
   run;
%mend output;

%output();

数据集 tst:

+---+---+
| a | b |
+---+---+
| 1 | 2 |
| 2 | 3 |
+---+---+

数据集 ds1:

+---+---+
| a | b |
+---+---+
| 1 | 2 |
+---+---+

数据集 ds2:

+---+---+
| a | b |
+---+---+
| 2 | 3 |
+---+---+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多