SAS循环宏变量解析不正确

时间:2017-03-21 19:47:54

标签: loops macros sas

下午好。

我正在编写一个SAS程序,它将遍历几组时间序列/观察。对于每组,每月有一次观察,总共大约450个观察/月。为简单起见,月份从1开始并按顺序移动。

现在,对于每组观察,我都有一组额外的变量。我正在导入一个辅助数据集,其中包含所有集合的这些变量,并使用&& var& i。结构为每个观察变量分配一个唯一的宏变量,在主循环执行期间调用。因此,例如,第一个观察中的所有变量都将“1”连接到它们的变量名称上,第二个观察变量具有“2”,依此类推。当主循环经历它的第一次迭代并调用&& var& i时,它将解析为& var1并从辅助数据集中提取从第一次观察分配的值。我测试了这个,它运行正常。

重要提示:辅助集中的每个观察都有一系列变量,称为 ratio_1 ratio_2 ,......最多为 ratio_9 。通过上面的宏分配后,他们会假设第一组的 ratio_11 ratio_21 ...的宏名称,以及 ratio_12 ,< em> ratio_22 ,......等后续集合。

当我尝试插入只应在每个集合中以非常特定的时间间隔发生的代码时,我的问题就出现了。每个集都有一个变量 initial_check ,用于确定此代码应在哪个月开始执行。然后,此代码应在每个以12个月为增量的观察中执行。因此,例如,set 1的 initial_check 值可能为36,这意味着代码只会在第35个月执行观察(请参阅下面的代码),随后执行第47,59个月, 71,等等。

第一行代码用于确定后面的代码仅以上述间隔执行( rem_var 检查当前月份与 initial_check之间差异的剩余部分,超过12 - 如果没有剩余,那么12个月的倍数已经过去了:

if mon >= %eval(&&initial_check&k -1) and rem_var = 0 and mon < &&term&k. then do ;

我已经单独运行该代码以检查其每个参数是否正在执行它应该做的事情,并且它似乎正常工作。接下来的代码如下:

** Iterate ratios ** 
if mon = %eval(&&initial_check&k. -1) then call symput('j',1) ;
else if mon = %eval(&&initial_check&k. +11) then call symput('j',2) ;
else if mon = %eval(&&initial_check&k. +23) then call symput('j',3) ;
else if mon = %eval(&&initial_check&k. +35) then call symput('j',4) ;
else if mon = %eval(&&initial_check&k. +47) then call symput('j',5) ;
else if mon = %eval(&&initial_check&k. +59) then call symput('j',6) ;
else if mon = %eval(&&initial_check&k. +71) then call symput('j',7) ;
else if mon = %eval(&&initial_check&k. +83) then call symput('j',8) ;
else if mon = %eval(&&initial_check&k. +95) then call symput('j',9) ;
end ;

同样,我使用非宏语言(即将值分配给常规变量 j )对此进行了测试,这似乎也有效。不幸的是,即使启用了“mprint”选项,我也看不到宏变量是否被正确分配。接下来,我有额外的代码,只有满足第一个条件才能执行。

if &&ratio_&j&k ne 0 then do ;

这就是问题所在:我收到一条说明宏变量 j 未解决的问题。 此代码仅应在已定义&amp; j 的实例中执行,因此我无法弄清楚它为何未解析。那个&amp;&amp; ratio_&amp; j&amp; k 应该在第35个月解析为&amp; ratio_11 ,在第47个月&amp; ratio_21 ,等等,为更广泛的计划的第一个循环。

我尝试过使用条件逻辑的宏版本(%IF,%THEN,%DO),但到目前为止还没有得到我想要的结果。

有人会碰巧有任何见解吗?我的智慧结束了。我将关注此主题,因此我可以在必要时添加详细信息。并提前感谢您花时间阅读本文。

1 个答案:

答案 0 :(得分:0)

我们需要更多信息。您不能在同一数据步骤中包含最后两个代码块,因为数据步骤将使用编译数据步骤时存在的宏变量J的值,而不是调用symput()函数生成的值。

为什么J不是数据步变量?

如果它是一个宏变量,并且您想使用调用symput()创建的值,那么您需要使用symget()(或symgetn())在运行时检索它。然后,您可以使用其值来生成实际要引用的宏变量的名称。

if symgetn(cats('ratio_',symgetn('j'),"&k")) ne 0 then do ;