【问题标题】:SAS: improve efficiency of array with macrosSAS:使用宏提高数组的效率
【发布时间】:2019-02-05 01:51:22
【问题描述】:

目前我正在尝试练习 SAS 宏,虽然它们在大多数情况下看起来合乎逻辑,但我在文档中几乎没有找到关于如何提高使用宏的数组效率的信息。有没有不同的方法,我做这一切都是错的?我想在工作中改进一些 SAS 代码,所以这只是一个我学习如何去做的简单示例。

这是我原来的基本数组代码:

data dataset_new;    
    set dataset_old;
    array array_one{12} value01-value12;
    do i = 1 to 12;  
        if array_one{i} = '121' then sponsor = 'yes';
        if array_one{i} in ('44', '55')  then participant = 'active';
    end;         
run;        

这是我尝试在其中添加宏的蹩脚尝试。

%let maximum = 10;   
%MACRO SPORTS(START,maximum);
data dataset_new;    
    set dataset_old;
    array array_one{12} value01-value12;
    %DO i = &START %TO &maximum ;
        if array_one{i} = '121' then sponsor = 'yes';
        if array_one{i} in ('44', '55')  then participant = 'active';
    %END;        
%MEND SPORTS;        
run;        

感谢您对如何执行此操作的任何想法。

【问题讨论】:

    标签: arrays sas sas-macro


    【解决方案1】:

    您正在混合范围,这通常是不可取的。

    您似乎想要的所谓改进是什么?

    %do 循环将为宏 %do 的每次迭代生成 2 个数据步 if 语句的源代码。

    宏外部的全局maximum 赋值对于设置或覆盖宏调用应该传递的maximum 没有任何作用。必须调用宏 SPORTS 才能发生任何事情,否则您只是在编译宏。宏定义也奇怪地与宏定义之外的run; 交错。在温柔中,你做错了。

    宏生成源代码,因此无法更改正在运行的源代码(因此已编译数据步骤)

    理论上,您可能希望

    if array_one{&i} = '121' then sponsor = 'yes';
    

    而不是

     if array_one{i} = '121' then sponsor = 'yes';
    

    但这在更广泛的意义上确实没有帮助。

    你是否真的尝试评估两者之间的差异

    do i = 1 to 12;  
        if array_one{i} = '121' then sponsor = 'yes';
        if array_one{i} in ('44', '55')  then participant = 'active';
    end;
    

    和宏生成的源码

        if value01 = '121' then sponsor = 'yes';
        if value01 in ('44', '55')  then participant = 'active';
        if value02 = '121' then sponsor = 'yes';
        if value02 in ('44', '55')  then participant = 'active';
        if value03 = '121' then sponsor = 'yes';
        if value03 in ('44', '55')  then participant = 'active';
        if value04 = '121' then sponsor = 'yes';
        if value04 in ('44', '55')  then participant = 'active';
        if value05 = '121' then sponsor = 'yes';
        if value05 in ('44', '55')  then participant = 'active';
        if value06 = '121' then sponsor = 'yes';
        if value06 in ('44', '55')  then participant = 'active';
        if value07 = '121' then sponsor = 'yes';
        if value07 in ('44', '55')  then participant = 'active';
        if value08 = '121' then sponsor = 'yes';
        if value08 in ('44', '55')  then participant = 'active';
        if value09 = '121' then sponsor = 'yes';
        if value09 in ('44', '55')  then participant = 'active';
        if value10 = '121' then sponsor = 'yes';
        if value10 in ('44', '55')  then participant = 'active';
        if value11 = '121' then sponsor = 'yes';
        if value11 in ('44', '55')  then participant = 'active';
        if value12 = '121' then sponsor = 'yes';
        if value12 in ('44', '55')  then participant = 'active';
    

    【讨论】:

    • 对不起,你是对的,这真是一团糟。我的家用电脑上没有 SAS,所以我只是写了一个简单的版本,说明我需要在工作中实现什么。所以我想为最大值添加一个宏,即:%let maximum = 10;现在我需要弄清楚它的去向。我应该仍然使用数组还是有更好的方法使用 %let maximum = 10; ?
    • 您可能会通过使用最大宏参数来仅控制数据步循环限制do I = 1 to &maximum 而没有%do 循环。这一切都取决于你真正想要什么。最好学习直接的数据步骤,然后减慢抽象的点点滴滴,使用宏变量来控制和管理抽象成实现(即代码生成)
    • 我不知道如何实现这一点,但我想要的是:array array_one{&maximum} value01-value&maximum;我会听从你关于“do”行代码的建议。
    • 了解数据步长数组使用的细节——DIM函数是数组中元素的数量。 DO I = 1 to DIM(array-name) ,或使用 UBOUND 和 HBOUND 来限制 DO 循环,如果数组定义的不是基本索引 1(SAS 默认)
    • 谢谢 - 我会对 DIM(数组名称)进行一些研究。
    猜你喜欢
    • 2021-08-04
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    相关资源
    最近更新 更多