SAS IML在循环中使用Mattrib和Macro(符号) [英] SAS IML use of Mattrib with Macro (symget) in a loop

查看:152
本文介绍了SAS IML在循环中使用Mattrib和Macro(符号)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在IML proc中,我具有多个列和多个带有列名称的向量:

In an IML proc I have several martices and several vectors with the names of columns:

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

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

To assign column names to columns in matrices one can copypaste the mattrib statement enough times:

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

但是,在我的情况下,矩阵的数量是在执行时定义的,因此需要执行do循环.以下代码

However, in my case the number of matrices is defined at execution, thus a do loop is needed. The following code

    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;

但是在第一个符号上会产生期望名称"错误.

however produces the "Expecting a name" error on the first symget.

类似的问题在SAS-IML中遍历名称?提供了宏symget的解决方法,在这里产生错误.

Similar question Loop over names in SAS-IML? offers the macro workaround with symget, what produces an error here.

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

What is the correct way of using mattrib with symget? Is there other way of making a variable from a string than macro?

任何帮助将不胜感激.

谢谢, 亚历克斯

EDIT1

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

The problem is in the symget function. The &-sign resolves the name of the matrix contained in the macro variable, the symget only returns the name of the macro.

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 问题

Function value solves the symget problem in EDIT1

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

mattrib 问题,但仍然存在.

已解决

感谢Rick,您对CALL EXECUTE()语句睁开了眼睛.

Thanks Rick, you have opened my eyes to CALL EXECUTE() statement.

推荐答案

使用CALL SYMPUTX时,不应在第二个参数中使用引号.您的声明

When you use CALL SYMPUTX, you should not use quotes for the second argument. Your statement

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

将字符串"mydata1"分配给宏变量.

assigns the string 'mydata1' to the macro variable.

通常,尝试在SAS/IML循环中使用宏变量通常会导致代码复杂.请参阅文章 SAS/IML语言中的宏和循环表示由于尝试将宏预处理器与交互式语言结合而导致的问题.因为MATTRIB语句期望矩阵名称为文字值,所以我建议您使用CALL EXECUTE而不是宏替换来执行MATTRIB语句.

In general, trying to use macro variables in SAS/IML loops often results in complicated code. See the article Macros and loops in the SAS/IML language for an indication of the issues caused by trying to combine a macro preprocessor with an interactive language. Because the MATTRIB statement expects a literal value for the matrix name, I recomend that you use CALL EXECUTE rather than macro substitution to execute the MATTRIB statement.

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

You are also having problems because a macro variable is always a scalar string, whereas the column name is a vector of strings. Use the ROWCAT function to concatenate the vector of names into a single string.

以下语句可在不使用宏变量的情况下实现您的目标:

The following statements accomplish your objective without using macro variables:

/* 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;

这篇关于SAS IML在循环中使用Mattrib和Macro(符号)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆