0

在 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 

有任何想法吗?


编辑2

函数解决EDIT1中的symget问题

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

mattrib问题但仍然存在


解决了

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

4

1 回答 1

0

使用 CALL SYMPUTX 时,不应将引号用于第二个参数。你的陈述

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

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

通常,尝试在 SAS/IML 循环中使用宏变量通常会导致代码复杂。请参阅SAS/IML 语言中的宏和循环一文,了解尝试将宏预处理器与交互式语言结合起来所导致的问题。因为 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;
于 2015-01-09T14:38:59.340 回答