在IML proc中,我有几个martices和几个带有列名称的向量:
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一起使用的正确方法是什么?是否有其他方法可以从字符串中创建变量而不是宏?
任何帮助都将不胜感激。
谢谢, 亚历
EDIT1
问题出在 symget 函数中。 & -sign解析宏变量中包含的矩阵的名称, 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
函数值解决了EDIT1中的 symget 问题
mydataNew = value(symget('mydataX'));
print (&mydataX);
print (value(symget("mydataX")));
print mydataNew;
mattrib 问题但仍然存在。
解决
谢谢Rick,你已经睁开眼睛看了CALL EXECUTE()语句。
答案 0 :(得分:0)
使用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;