首页 > 解决方案 > call symput 究竟是如何工作的 - 尝试在 call symput 的帮助下创建一个迭代器

问题描述

我正在编写修改上一个数据步骤中声明的数组的代码。由于它是一个新的数据步,旧索引将不起作用。我想我可以在 call symput 函数的帮助下使用迭代器。我试图为每个 MID_(i) 数组元素分配 0 值,其中 month < "i" 所以我想出了代码:

data want;
set summary;
do i=1 to &MAX_MONTH.;
    call symputx('iterator',i);
    if MONTH < &iterator. then MID_&iterator. = 0;
end;run;

它不起作用。我正在试验代码来调试它并插入一个常量值而不是“i”:

data want;
set summary;
do i=1 to &MAX_MONTH.;
    call symputx('iterator',7);
    if MONTH < &iterator. then MID_&iterator. = 0;
end;run;

更让我困惑的是,这段代码只能工作一次。当我将“7”更改为其他数字时,结果保持不变,直到我重置 SAS,之后它将使用更改的值,但仍然 - 只有一次。

这里会发生什么?我不明白什么?如何创建一个工作迭代器?

标签: arraysloopssasiterator

解决方案


宏处理器首先将宏表达式转换为文本。因此&MAX_MONTH&iterator在 SAS 甚至开始编译数据步骤之前,并且肯定在它有机会运行 CALL SYMPUTX() 或 IF 语句之前,它们的值已经被替换。

因此,如果 MAX_MONTH 的值为 12,而 ITERATOR 的值为 7,那么您运行以下数据步骤:

data want;
  set summary;
  do i=1 to 12;
    call symputx('iterator',i);
    if MONTH < 7 then MID_7 = 0;
  end;
run;

这与运行相同:

data want;
  set summary;
  if MONTH < 7 then MID_7 = 0;
  i=13;
run;
%let iterator=12;

ARRAY 语句是用于通过变量在列表中的位置来引用变量的数据步骤方法。因此,如果您想引用名称为 MID_1、MID_2 等的变量,请定义一个数组并使用数组的索引。您仍然可以使用 MAX_MONTH 宏变量来定义要包含在数组中的变量集。

所以也许你打算运行这样的东西:

data want;
  set summary;
  array mid_ [&max_month] ;
  do index=month+1 to dim(mid_);
    MID_[index] = 0;
  end;
  drop index;
run;

推荐阅读