12-06-2017 01:10 PM
I want to run the following code (see below). I am looping through all the y variables within my macro and calling the x variables when I call the macro "simpleC" in. My question is this: How can I simultaneously loop through two variables within the loop? I know how to do this with an array in a datastep but not within a macro.
So when y = outcomevar1, we need to have
and when y= outcomevar2, we need to have
Is there a way I can modify the
%do i = 1 %to %sysfunc(countw(&varlist)); /*Modify this!!!*/ %let tabit = %scan(&varlist, %eval(&i)); %let subset = %scan(&varlistB, %eval(&i)); /*This is what I thought I could do, but is incorrect*/
lines to include this? It doesn't like the
%let subset = %scan(&varlistB, %eval(&i));
line. I'm already looping through the y variables but I don't know how to match two variables and loop through a set at the same time. I don't want to have a nested do loop because I don't want to run, say y = outcomevar1 and subsetcatvar2 at the same time. I tried searching for this in the previous answered questions on the boards, but was unable to figure it out. I really do appreciate your help and hope that my code and explanation is sufficient. If not, I can further elaborate. Thanks!
Here is my code:
%let cont = contvar1
%let MHcont = outcomevar1 outcomevar2; %let varlistB = subsetvar1 Subsetvar2; %macro simpleC(xvar, output, model); %do o = 0 %to 1; %if &o = 1 %then %do; %let outType = MH; %let dom = Domain4. ; %let varlist = &MHcont ; %end; /*for MH variables*/ %else %do; %let outType = ; %let dom = ; %let varlist = &cont; %end; /*Now, we do this for each outcome*/ %do i = 1 %to %sysfunc(countw(&varlist)); /*Modify this!!!*/ %let tabit = %scan(&varlist, %eval(&i)); %let subset = %scan(&varlistB, %eval(&i)); /*This is what I thought I could do, but is incorrect*/ proc surveyreg data = &cleanData; class &xvar; model &tabit = &xvar / solution ; weight ps_wgt; strata strata_cat; %if &outType = MH %then domain subset_cat * ⊂; ods output %if &outType = MH %then SurveyReg.DependentVariable.&dom.DomainSummary = aDataSummary; %else SurveyReg.DependentVariable.&dom.DataSummary = aDataSummary; run; %end; /*This ends the loop around each outcome (i=1 to n.outcomes) and its corresponding subsetting variable (see &varlistb)*/ %end; /*This ends the loop looking at MH vs non-MH outcomes. (o = 0 to 1)*/ %simpleC (race7, /*Variable used*/ race, /* name of dataset to be written: outcome_race */ 1 /* Model number - used for stacking bivariates then merging w/ other model results later */ ); %simpleC (%str(race7 q08 q127), All, /* name of dataset to be written: outcome_All */ 5 /* Model number - used for stacking bivariates then merging w/ other model results */ );
12-06-2017 01:25 PM
You may want to investigate having the values you want in a data set and use a data _null_ data step with that data to make call execute create your macro calls.
BTW this part of your macro call
doesn't require the %str.
%macro dummy(var); %put Var resolves to: &var; %mend; %dummy(race7); %dummy(race7 q08 q127);
You would only need the %str if you need a special character such as comma (which would otherwise be interpreted as a delimiter for the macro parameters) a semicolon (which would be treated as a misplaced statement ender), or special characters as documented. A simple space-delimited list of variable names isn't going to be a problem. Though I would recommend using keyword parameters a much as practical.
12-06-2017 02:06 PM - edited 12-06-2017 02:07 PM
Just a few comments to see if any of them stick ...
First, you absolutely can do what you are asking to do. The problem lies elsewhere. If you were to turn on the usual debugging options, SAS might make it obvious where the problem lies:
options symbolgen mlogic mprint;
These are usually overkill, but helpful for a complex debugging situation.
Second, your ODS OUTPUT statement is missing a semicolon. That needs to be added before the RUN statement.
Third, %EVAL(&I) is overkill. Since there's no math being performed there, &I would be enough (without %EVAL). Obviously a minor point.
Finally, it might be a little clearer to read/write/update the program if you used this structure:
%if &outtype=MH %then %do;
Then insert the code for both the DOMAIN and the ODS OUTPUT statements as appropriate.