【问题标题】:Using a vector generated in SAS/IML as a macro variable使用 SAS/IML 中生成的向量作为宏变量
【发布时间】:2014-07-30 16:25:01
【问题描述】:

我正在编写一个宏,它将运行 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 MIXED 代码中的 PARMS 语句,该代码可以正常工作。然而,当我按原样运行代码时,SAS 显然将文字字符串 'start_vector[label=""]' 放在 PARMS 之后,而不是列出 IML 生成的值。

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

【问题讨论】:

    标签: sas sas-macro sas-iml


    【解决方案1】:

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

    这是将向量放入宏变量中的单个字符串的一种方法。

    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;
    

    【讨论】:

    • 谢谢,乔。我之前尝试过 SYMPUT,但 SYMPUT 要求将原始数据格式化为文本。由于 START_VECTOR 生成为数字,因此在使用 SYMPUT 时出现以下错误:错误:(执行)数字参数应该是字符。
    • SYMPUTX 将为您转换(或者您可以自己转换)。您可能想使用CHAR 在数字后添加一个空格(或某种分隔符),如果它会将它们压扁。
    • 我使用了下面的代码但得到了同样的错误:proc iml; start_vector = symsqr(I(&nvars));调用 symputx("start_vector",rowcat(start_vector`)); %put &start_vector;退出;
    • 你需要把它变成一个单行字符向量。请参阅上文了解我的建议(还有很多其他方法)。
    【解决方案2】:

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

    您必须将其包装在宏中吗?如果是这样,则 SUBMIT 和 ENDSUBMIT 语句将不起作用,因为它们不能从宏中调用。但是,由于 SAS/IML 可以定义和调用带参数的模块,所以我通常会避免使用宏语言,而是定义一个带参数的模块,然后直接调用该模块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 1970-01-01
      • 2019-04-22
      • 2014-12-02
      相关资源
      最近更新 更多