SAS宏扫描和评估有问题

时间:2012-04-19 18:18:02

标签: macros sas

我正在尝试实现一个宏,它允许我运行几个逻辑回归模型,这些模型具有相同的结果但是对于几个数据集具有不同的主要解释变量(所有模型的协变量都是共同的)。我编写了一个扫描和eval宏来扫描两个全局变量,但它并没有完全正常工作。代码如下所示:

%let numbers=5 7 8 9 10 12 13 14 16 18 19 24  26 
32 33  35 37  39  41  44 45  48 50 52 
55 56  58  66 67 68 ; 

%let list=voting national local safe street violence say free;

%macro logistic;    
%let j=1;
%let m=1;
%let first=%scan(&list,%eval(&j));
%let second=%scan(&numbers,%eval(&m));
%do %while (&first ne );
%do %while (&second ne );

proc logistic data=socialcapital&second. descending;
model depression= &first. agec married edu inc_2 inc_3 inc_4 inc_5/risklimits;
ods output ParameterEstimates=mv_model1&second._&first.;
run;

%let j=%eval(&j+1);
%let m=%eval(&m+1);
%let first=%scan(&list,%eval(&j));
%let second=%scan(&numbers,%eval(&m)); 
%end;
%end;
run;

%mend;  
%logistic;

全局变量数是指我正在使用的“socialcaptial”数据集。每个数据集代表一个国家,因此“数字”全局变量中的每个数字都指数据集。全局变量列表是指我想要包含在模型中的主要解释变量列表,每个模型一个主要解释变量。我希望得到的是每个国家的8个独立的多变量逻辑回归结果。

然而,似乎扫描功能对我来说不正常,所以我知道我做错了什么,但我不确定是什么。似乎宏将& list中的1个变量从&数字分配给1个数据集,直到它用完& list中的变量,并且只使用协变量运行模型而不是使用数据集5运行所有8个模型,然后使用数据集7再次运行所有8个模型,依此类推。

基本上,我用编号搞砸了一些东西,我不太清楚如何继续使用这个宏。我知道我可以通过在proc logistic中使用带有堆叠数据集的“by语句”来摆脱&数字全局变量,但我真的想学习如何使这个适用于未来的模型,而这些模型可能不是选项。

3 个答案:

答案 0 :(得分:0)

玛吉,

我相信下面的代码会做你想要的。我注释掉了LOGISTIC程序并输入了一个PUT语句进行测试,它似乎解决了我认为应该如此的方式。

%let numbers=5 7 8 9 10 12 13 14 16 18 19 24  26 
32 33  35 37  39  41  44 45  48 50 52 
55 56  58  66 67 68 ; 

%let list=voting national local safe street violence say free;

%macro logistic;
   %let j=1;
   %let first=%scan(&list,%eval(&j));
   %do %while (&first ne );
      %let m=1;
      %let second=%scan(&numbers,%eval(&m));
      %do %while (&second ne );

        /*
         proc logistic data=socialcapital&second. descending;
         model depression= &first. agec married edu inc_2 inc_3 inc_4 inc_5/risklimits;
         ods output ParameterEstimates=mv_model1&second._&first.;
         run;
        */
         %put J=&j - M=&m - FIRST=&first - SECOND=&second;

         %let m=%eval(&m+1);
         %let second=%scan(&numbers,%eval(&m));
      %end;
      %let j=%eval(&j+1);
      %let first=%scan(&list,%eval(&j));
   %end;
   run;
%mend;

%logistic;

答案 1 :(得分:0)

这是另一种方法:(如果你最终在数据集中使用NUMBERS和LIST,我们也可以改变代码来处理它)

%let numbers=5 7 8 9 10 12 13 14 16 18 19 24  26 
 32 33  35 37  39  41  44 45  48 50 52 
 55 56  58  66 67 68 ; 

%let list=voting national local safe street violence say free;

%macro logistic(First=, Second=);    
 %Put FIRST= &first;
 %Put SECOND= &second;
 /*proc logistic data=socialcapital&second. descending;*/
 /*model depression= &first. agec married edu inc_2 inc_3 inc_4 inc_5/risklimits;*/
 /*ods output ParameterEstimates=mv_model1&second._&first.;*/
 /*run;*/

%mend logistic;  

%Macro Test;
 %do i = 1 %to %sysfunc(countw(&list));
  %Let first=%scan(&list,&i);
  %do j = 1 %to %sysfunc(countw(&numbers));
   %Let second=%scan(&numbers,&j);
   %logistic(First=&first,Second=&second)
  %end;
 %end;
%Mend test;
%test

答案 2 :(得分:0)

哎呀,小修正。我应该使用“数字”而不是下面的索引“i”。

您可以使用宏执行此操作,但您也可以在数据步骤(使用调用执行)或Proc IML(使用9.22或更高版本)中执行此操作,并在循环中嵌套提交块。要了解相关信息,请参阅下文。

Data _Null_;
 Do numbers = 5, 7, 
                  8 to 10, 
                  12 to 14, 
                  16, 18, 19, 24, 26, 32, 
                  33 to 41 by 2, 
                  44, 45, 48, 50, 52, 55, 56, 58, 
                  66 to 68;  
   Do IndpVar = "voting", "national", "local", "safe", "street", "violence", "say", "free";
       call execute( '%Put '||strip(Indpvar)||strip(put(numbers,best.))||';');
      "Logistic Code Goes Here";
   End;
   End;
 Run;