【问题标题】:Resolving macro containing %eval in macro variable name, SAS解析宏变量名称中包含 %eval 的宏,SAS
【发布时间】:2016-03-07 23:18:10
【问题描述】:

这是一个玩具示例,旨在帮助我解决更大的问题。它本质上涉及在引用更大的宏变量名称时使用 %eval() 宏。

我创建了一个宏变量x_2,它使用循环的值'&it',从最终输出中可以看出,该变量已成功创建,但是我只能将其放入日志而不评估&it+ 1,当使用大于 1 的循环时,我需要这样做。

似乎先解决 x_,给出警告,然后再评估 x_2 作为一个整体并给出输出。

我意识到这只是一个关于如何正确引用宏的问题,但我找不到任何将评估用作宏变量名一部分的示例。

谢谢。

%macro testing;

%DO it = 1 %TO 1; 

data dataset;
    s=100;
    t=99;
run;

data _null_;
    set dataset;
    if s = 100 then do;
        call symput("x_%eval(&it+1)",t);
    end;
run;

%put "&x_%eval(&it+1)";

%put &x_2;

%END;

%mend testing;

%testing;

日志输出

MLOGIC(TESTING):  %PUT "&x_%eval(&it+1)"

WARNING: Apparent symbolic reference X_ not resolved.

SYMBOLGEN:  Macro variable IT resolves to 1

SYMBOLGEN:  Macro variable X_2 resolves to           99

"          99"

MLOGIC(TESTING):  %PUT &x_2

SYMBOLGEN:  Macro variable X_2 resolves to           99

99

MLOGIC(TESTING):  %DO loop index variable IT is now 2; loop will not iterate again.

MLOGIC(TESTING):  Ending execution.

【问题讨论】:

    标签: variables macros sas eval


    【解决方案1】:

    确实,SAS 在调用 %eval 函数之前进行了变量替换 最简单的解决方案是在前面的语句中调用 %eval

    %let xNr = %eval(&it+1);
    %put "&&x_&xNr";
    

    双 & 符号用于延迟 x_&xNr 的评估,直到 &xNr 评估为 2 并且没有 x_ 未定义的警告。

    SYMBOLGEN:  Macro variable IT resolves to 1
    SYMBOLGEN:  && resolves to &.
    SYMBOLGEN:  Macro variable XNR resolves to 2
    SYMBOLGEN:  Macro variable X_2 resolves to           99
    "          99"
    

    【讨论】:

    • 谢谢你,我一直在尝试各种组合来做一条线(类似于昆汀和盛林,他们实际上是成功的),我没想过要分开它!
    【解决方案2】:

    同意德克的回答。但作为一个思考练习,可以通过丑陋地使用引用函数来达到预期的结果:

    %let x_2=99;
    %let it=1;
    %put %unquote(%nrstr(&x_)%eval(&it+1));
    

    所以 %nrstr 隐藏 & 直到 %eval 完成其工作(我认为。:)

    更新:

    @Shenglin 在评论中添加了一个类似的答案,我比上面的方法更喜欢:

    %put %superq(x_%eval(&it+1));
    

    这是因为 %superq() 在将宏变量名称作为参数(没有前导 &)而不是宏变量引用时是不寻常的。所以你可以使用 %EVAL 来生成宏变量的部分名称。如果需要,您可以 %unquote(),但这不是必需的。

    【讨论】:

    • 谢谢,我太专注于尝试在一行中解决它我错过了更简单的两行解决方案,但很高兴看到它是可能的。
    【解决方案3】:

    将宏变量名构建到另一个变量中然后扩展值要容易得多。

    %let t2=found;
    %let mvar=t%eval(1+1);
    %put &&&mvar;
    

    【讨论】:

    • 如果你只有一个变量的编号列表(值得我点赞),这非常优雅,但如果你有两个列表,例如X_1X_2,则不是这样。 X_3, ... 和 Y_1, Y_2, Y_3, ...
    【解决方案4】:

    你能试试"&&x_%eval(&it+1)"吗?

    【讨论】:

    • 好主意,但不幸的是,这还不足以阻止 SAS 尝试解析 &x_。
    • 用这个试试 %superq:%put %superq(x_%eval(&it+1));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多