1

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

%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;

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

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

基本上,我把编号弄乱了,我不太确定如何继续使用这个宏。我知道我可以通过在具有堆叠数据集的 proc 逻辑中使用“by 语句”来摆脱 &numbers 全局变量,但我真的很想学习如何让它适用于可能无法选择的未来模型。

4

3 回答 3

1

哎呀,小修正。我应该在下面使用“数字”而不是索引“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;
于 2012-05-16T14:21:12.493 回答
1

这是另一种方法:(如果您最终在数据集中使用 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
于 2012-04-19T23:11:00.533 回答
1

劣质煤,

我相信下面的代码会做你想做的事。我注释掉了 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;
于 2012-04-19T19:08:01.320 回答