SAS-使用动态宏变量创建数据步骤变量



我想使用调用symput将数据步骤变量的实例存储在宏变量中,然后在同一数据步骤中使用该宏变量来填充新字段,每36条记录为其分配一个新值。

我尝试了以下代码:

data a;
set a;
if MOB = 1 then do;
MOB1_accounts = accounts;
call symput('MOB1_acct', MOB1_accounts);
end;
else if MOB > 1 then MOB1_accounts = &MOB1_acct.;
run;

我有一系列重复的MOB(1-36(。我想创建一个名为MOB1_Accts的字段,将其设置为MOB=1的队列的账户数,并在MOB=2、3、4等时保持该值;向下拖动";每36条记录的MOB 1值。

由于某种原因,这个宏变量正在返回"0";1〃;而不是正确的#帐户。我认为这可能是一个字符/数字问题,但不确定。我试过每种可能的单引号、双引号、符号等排列……运气不好。

谢谢你的帮助!

您滥用了宏系统。

源代码中的符号(&(引导器告诉SAS解析以下符号并将其放入代码提交流中。因此,解析的&MOB1_acct.不能在运行的DATA步骤中更改。换句话说,正在运行的步骤不能更改其源代码——解析的宏变量对于该步骤的所有隐式迭代都是相同的,因为它的值成为了该步骤源代码的一部分。

您可以使用SYMPUT()SYMGET()函数将字符串移出DATA步骤并移入DATA步骤。但这仍然是解决问题的错误方法。

最直接的技术可能是

  • 使用retained变量
  • CCD_ 6计算以确定每36个行。(_n_是具有单个SET的简单步骤中的行号的代理。(

示例:

data a;
set a;
retain mob1_accounts;
* every 36 rows change the value, otherwise the value is retained;
if mod(_n_,36) = 1 then mob1_accounts = accounts;
run;

您没有显示任何数据,因此您需要的实际程序语句可能略有不同。

SYMPUT/SYMGETRETAIN的对比

如上所述,SYMPUT/SYMGET是通过将值存储在宏符号表中来保留值的一种可能方式。不过有一个点球。SYM*需要一个函数调用和正在发生的任何机制/黑盒来存储/检索符号值,并可能需要字符和数字之间的额外转换。

示例:

已读取1000000行。DATA _null_步骤以避免作为对比的一部分的写入开销。

data have;
do rownum = 1 to 1e6;
mob + 1;
accounts = sum(accounts, rand('integer', 1,50) - 10);
if mob > 36 then mob = 1;
output;
end;
run;
data _null_;
set have;
if mob = 1 then call symput ('mob1_accounts', cats(accounts));
mob1_accounts = symgetn('mob1_accounts');
run;
data _null_;
set have;
retain mob1_accounts;
if mob = 1 then mob1_accounts = accounts;
run;

在我的系统日志

142  data _null_;
143    set have;
144
145    if mob = 1 then call symput ('mob1_accounts', cats(accounts));
146
147    mob1_accounts = symgetn('mob1_accounts');
148  run;
NOTE: There were 1000000 observations read from the data set WORK.HAVE.
NOTE: DATA statement used (Total process time):
real time           0.34 seconds
cpu time            0.34 seconds

149
150  data _null_;
151    set have;
152    retain mob1_accounts;
153
154    if mob = 1 then mob1_accounts = accounts;
155  run;
NOTE: There were 1000000 observations read from the data set WORK.HAVE.
NOTE: DATA statement used (Total process time):
real time           0.04 seconds
cpu time            0.03 seconds

way          real   cpu
------------- ------  ----
SYMPUT/SYMGET   0.34  0.34
RETAIN      0.04  0.03

最新更新