【问题标题】:SAS IML use of Mattrib with Macro (symget) in a loopSAS IML 在循环中使用带有宏(symget)的 Mattrib
【发布时间】:2015-03-06 10:03:54
【问题描述】:

在 IML 过程中,我有几个矩阵和几个带有列名称的向量:

proc IML;
    mydata1 = {1 2 3, 2 3 4};
    mydata2 = {1 2, 2 3};
    names1 = {'red'  'green' 'blue'};
    names2 = {'black' 'white'};

要将列名分配给矩阵中的列,可以复制粘贴 mattrib 语句足够多次:

    /*  mattrib mydata1 colname=names1;*/
    /*  mattrib mydata2 colname=names2;*/

但是,在我的例子中,矩阵的数量是在执行时定义的,因此需要一个 do 循环。以下代码

    varNumb=2;
    do idx=1 to varNumb;
        call symputx ('mydataX', cat('mydata',idx));
        call symputx ('namesX', cat('names',idx));
        mattrib (symget('mydataX')) colname=(symget('namesX'));
    end;

    print (mydata1[,'red']) (mydata2[,'white']);
quit;

但是在第一个 symget 上会产生“期望名称”错误。

类似的问题Loop over names in SAS-IML? 提供了使用 symget 的宏解决方法,这里会产生错误。

将 mattrib 与 symget 一起使用的正确方法是什么?除了宏,还有其他方法可以从字符串中生成变量吗?

任何帮助将不胜感激。

谢谢, 亚历克斯


编辑1

问题出在 symget 函数中。 &-符号解析包含在宏变量中的矩阵的名称,symget只返回宏的名称。

proc IML;
    mydata1 = {1 2 3};
    call symputx ('mydataX', 'mydata1');
    mydataNew = (symget('mydataX'));

    print (&mydataX);
    print (symget("mydataX"));
    print mydataNew;
quit;

结果

mydata1 :   
1 2 3 

mydata1 

mydataNew :  
mydata1 

有什么想法吗?


EDIT2

函数value解决EDIT1中的symget问题

    mydataNew = value(symget('mydataX'));
    print (&mydataX);
    print (value(symget("mydataX")));
    print mydataNew;

mattrib 问题仍然存在。


已解决

感谢 Rick,你让我看到了 CALL EXECUTE() 语句。

【问题讨论】:

    标签: macros sas-iml string-to-symbol


    【解决方案1】:

    当您使用 CALL SYMPUTX 时,您不应在第二个参数中使用引号。你的陈述

    call symputx ('mydataX', 'mydata1');
    

    将字符串“mydata1”分配给宏变量。

    一般来说,尝试在 SAS/IML 循环中使用宏变量通常会导致代码复杂。请参阅文章Macros and loops in the SAS/IML language,了解尝试将宏预处理器与交互式语言结合起来所导致的问题。因为 MATTRIB 语句需要矩阵名称的文字值,所以我建议您使用 CALL EXECUTE 而不是宏替换来执行 MATTRIB 语句。

    您也遇到了问题,因为宏变量始终是标量字符串,而列名是字符串向量。使用 ROWCAT 函数将名称向量连接成单个字符串。

    以下语句无需使用宏变量即可实现您的目标:

    /* Use CALL EXECUTE to set matrix attributes dynamically.
       Requires that matrixName and varNames be defined at main scope */
    start SetMattrib;
       cmd =  "mattrib " + matrixName + " colname={" + varNames + "};";
       *print cmd;    /* for debugging */
       call execute(cmd);
    finish;
    
    varNumb=2;
    do idx=1 to varNumb;
        matrixName = cat('mydata',idx);
        varNames = rowcat( value(cat('names',idx)) + " " );
        run SetMattrib;
    end;
    

    【讨论】:

      猜你喜欢
      • 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
      相关资源
      最近更新 更多