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

SAS-使用动态宏变量创建数据步长变量,sas,Sas,我想使用call 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.;

我想使用call 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;
我有一系列重复的暴徒(1-36)。我想创建一个名为MOB1_Accts的字段,将其设置为MOB=1的队列的#个帐户,并在MOB=2、3、4等时保留该值。我基本上希望每36条记录“向下拖动”MOB 1值

出于某种原因,此宏变量返回“1”而不是正确的#帐户。我认为这可能是一个字符/数字问题,但不确定。我已经尝试了单引号、双引号、符号等各种可能的排列方式。。。不走运


谢谢你的帮助

您误用了宏系统

源代码中的符号(
&
)介绍人告诉SAS解析以下符号并将其放入代码提交流中。因此,在运行数据步骤中,无法更改已解析的
&MOB1\u账户
。换句话说,正在运行的步骤不能更改其源代码——解析的宏变量对于该步骤的所有隐式迭代都是相同的,因为其值已成为该步骤源代码的一部分

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

最直接的技术可能是

  • 使用
    retain
    ed变量
  • mod(\n\u36)
    计算以确定每36行。(
    \u n
    是一个简单步骤中的行号代理,只需一个集合。)
例如:

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/SYMGET
RETAIN

如上所述,
SYMPUT/SYMGET
是一种通过关闭宏符号表中的存储来保留值的可能方法。不过还是有处罚的。
SYM*
需要一个函数调用和任何正在进行的阴谋/黑盒操作来存储/检索符号值,还可能需要在字符和数字之间进行额外的转换

例如:

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;
读取1000000行<代码>数据_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


由于某些原因,我的呼叫symput+symget/symgetn仍然只返回“1”。但retain语句工作得非常好。我不知道我怎么直到现在才听说它-非常感谢!