使用SAS/IML中生成的向量作为宏变量

使用SAS/IML中生成的向量作为宏变量,sas,sas-macro,sas-iml,Sas,Sas Macro,Sas Iml,我正在编写一个宏,它将运行PROC MIXED,并使用PARMS语句将1级剩余方差固定为接近零值。我试图使用SAS/IML生成PARMS语句的大部分起始值,类似于: %macro test (dataset= , classroom= , preds= , outcome=); proc iml; /*count number of variables*/ %let nvars = 0; %do %while(%qscan(&preds,&nvars+1,%s

我正在编写一个宏,它将运行PROC MIXED,并使用PARMS语句将1级剩余方差固定为接近零值。我试图使用SAS/IML生成PARMS语句的大部分起始值,类似于:

%macro test (dataset= , classroom= , preds= , outcome=);
proc iml;

/*count number of variables*/
    %let nvars = 0; 
    %do %while(%qscan(&preds,&nvars+1,%str( )) ne %str());
        %let nvars = %eval(&nvars+1);
    %end; 

/*determine location of level-1 residual in the start value vector*/
    %let error_location = %eval(((&nvars*(&nvars-1))/2)+&nvars+1);

/*create vector of start values from lower triangle of identity matrix*/
    start_vector = symsqr(I(&nvars));
    %let starts = %str(start_vector[label=""]); 

/*analyze data*/
    proc mixed data=&dataset noprofile method=ml;
        class &classroom;
        model &outcome = &preds /noint;
        random &preds /type=un sub=&classroom g; 
        parms 
            &starts
            .00000001 /hold= &error_location;
    run;
quit;
%mend;
在PROC混合代码中没有PARMS语句,代码运行良好。但是,当我按原样运行代码时,SAS显然会将文本字符串“start_vector[label=”“]”放在PARMS之后,而不是列出IML生成的值


如何避免此错误并让SAS将START_VECTOR中包含的值指定为PARMS语句的起始值?

您应该使用SAS/IML中的
SYMPUT
SYMPUTX
例程将向量转换为宏变量

proc iml;
  start = {"Hi","Bye"};
  call symput("start",rowcat(start`));
  %put &start;
quit;
这是将向量转换为宏变量中单个字符串的一种方法

proc iml;
  start = {"Hi","Bye"};
  call symput("start",rowcat(start`));
  %put &start;
quit;
对于数值向量,您需要使用
char
将其转换为:

proc-iml; 起始向量=j(5); 调用symputx(“开始向量”,rowcat(char(j)); %put&start_向量; 退出

对于数值矩阵,您需要使用
形状
将其展平:

proc iml; 
    start_vector = j(5,5); 
    call symputx("start_vector",rowcat(shape(char(start_vector),1))); 
    %put &start_vector;
quit;

您的问题和两个解决方案将在文章中讨论”


您必须将其包装在宏中吗?如果是这样,SUBMIT和ENDSUBMIT语句将无法工作,因为它们不能以宏的形式调用。但是,由于SAS/IML允许您使用参数定义和调用模块,因此我通常避免使用宏语言,而是定义一个接受参数的模块,然后直接调用该模块。

谢谢,Joe。我以前尝试过SYMPUT,但SYMPUT要求将原始数据格式化为文本。由于START_VECTOR是以数字形式生成的,所以在使用SYMPUT时,我得到以下错误:错误:(执行)数字参数应该是字符。
SYMPUTX
将为您转换它(或者您可以自己转换)。如果将数字压扁,您可能需要使用
CHAR
在数字(或某种类型的delimter)后添加空格;开始向量=symsqr(I(&nvars));调用symputx(“start_vector”,rowcat(start_vector`));%put&start\u向量;退出您需要将其放入单行字符向量中。我的建议见上文(还有很多其他方法)。