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

时间:2014-07-30 16:25:01

标签: sas sas-macro sas-iml

我正在编写一个宏,它将使用PARMS语句运行PROC MIXED,其中一级残差方差固定为接近零的值。我试图使用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 MIXED代码中的PARMS语句。但是,当我按原样运行代码时,SAS显然会将文字字符串" start_vector [label =""]'在PARMS之后而不是列出IML生成的值。

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

2 个答案:

答案 0 :(得分:1)

您应该使用SAS / IML中的SYMPUTSYMPUTX例程将矢量转换为宏变量。

这是将矢量转换为宏变量中的单个字符串的一种方法。

proc iml;
  start = {"Hi","Bye"};
  call symput("start",rowcat(start`));
  %put &start;
quit;

使用数字向量,您需要使用char进行转换:

proc iml;     start_vector = j(5);     调用symputx(“start_vector”,rowcat(char(j)));     %put& start_vector; 退出;

使用数字矩阵,您需要使用SHAPE来展平它:

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

答案 1 :(得分:1)

文章" Passing values from PROC IML into SAS Procedures中讨论了您的问题和两种解决方案。"

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