2012-04-19 1 views
1

Я пытаюсь реализовать макрос, который позволит мне запустить несколько моделей логистической регрессии, которые имеют один и тот же результат, но другую основную пояснительную переменную (ковариаты будут распространены для всех моделей) для нескольких наборы данных. Я написал макрос сканирования и eval, который сканирует две глобальные переменные, но он не совсем работает. Код показан ниже:Проблема с SAS macro scan и 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 отдельных многопараметрических результатов регрессии логистики для каждой страны.

Однако, похоже, что функция сканирования работает неправильно, поэтому я знаю, что я сделал что-то неправильно, но я не уверен, что. Кажется, что макрос присваивает 1 переменную из & списка в 1 набор данных из & номеров до тех пор, пока не закончится переменная из & и просто запустит модель только с ковариатами вместо запуска всех 8 моделей с использованием набора данных 5, а затем запустив все 8 модели снова с использованием набора данных 7 и т. д.

В принципе, я перепутал что-то с нумерацией, и я не совсем уверен, как продолжить этот макрос. Я знаю, что могу избавиться от глобальной переменной &, используя «оператор» в proc-логике с накопленным набором данных, но мне бы очень хотелось узнать, как заставить это работать для будущих моделей, где это может быть не вариант ,

ответ

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

Вот еще один способ сделать это: (если вы в конечном итоге с цифрами и 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 
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; 

 Смежные вопросы

  • Нет связанных вопросов^_^