## IF THEN DO alternative

Solved
Occasional Contributor
Posts: 17

# IF THEN DO alternative

I'm using PC SAS v9.3.  I have some conditional logic that looks like this...

DATA CPA_PST(KEEP=REG LCD VARPST MEANPOST MOS);

SET CPA_PST;

IF MOS = 3 THEN DO; VARPST = VAR(OF MONS1 - MONS3); MEANPOST = MEAN(OF MONS1 - MONS3); END;

ELSE IF MOS = 4 THEN DO; VARPST = VAR(OF MONS1 - MONS4); MEANPOST = MEAN(OF MONS1 - MONS4); END;

ELSE IF MOS = 5 THEN DO; VARPST = VAR(OF MONS1 - MONS5); MEANPOST = MEAN(OF MONS1 - MONS5); END;

ELSE IF MOS = 6 THEN DO; VARPST = VAR(OF MONS1 - MONS6); MEANPOST = MEAN(OF MONS1 - MONS6); END;

ELSE IF MOS = 7 THEN DO; VARPST = VAR(OF MONS1 - MONS7); MEANPOST = MEAN(OF MONS1 - MONS7); END;

ELSE IF MOS = 8 THEN DO; VARPST = VAR(OF MONS1 - MONS8); MEANPOST = MEAN(OF MONS1 - MONS8); END;

ELSE IF MOS = 9 THEN DO; VARPST = VAR(OF MONS1 - MONS9); MEANPOST = MEAN(OF MONS1 - MONS9); END;

ELSE IF MOS = 10 THEN DO; VARPST = VAR(OF MONS1 - MONS10); MEANPOST = MEAN(OF MONS1 - MONS10); END;

ELSE IF MOS = 11 THEN DO; VARPST = VAR(OF MONS1 - MONS11); MEANPOST = MEAN(OF MONS1 - MONS11); END;

ELSE IF MOS = 12 THEN DO; VARPST = VAR(OF MONS1 - MONS12); MEANPOST = MEAN(OF MONS1 - MONS12); END;

ELSE IF MOS = 13 THEN DO; VARPST = VAR(OF MONS1 - MONS13); MEANPOST = MEAN(OF MONS1 - MONS13); END;

ELSE IF MOS = 14 THEN DO; VARPST = VAR(OF MONS1 - MONS14); MEANPOST = MEAN(OF MONS1 - MONS14); END;

ELSE IF MOS = 15 THEN DO; VARPST = VAR(OF MONS1 - MONS15); MEANPOST = MEAN(OF MONS1 - MONS15); END;

RUN;

However I could (and probably will) have a different max number of mons to calculate going forward.  Rather than having to manually add a line each month, is there a way to use mos as my max mons value?  I'm thinking something like this...

DATA CPA_PST(KEEP=REG LCD VARPST MEANPOST MOS);

SET CPA_PST;

VARPST = VAR(OF MONS1 - 'MONS'||trim(left(mos))); MEANPOST = MEAN(OF MONS1 - 'MONS'||trim(left(mos)));

RUN;

...but SAS has no idea what I'm talking about.  I'm just at a loss as to how to do this.  Any help is appreciated!

Accepted Solutions
Solution
‎02-22-2017 11:40 AM
Super User
Posts: 10,626

## Re: IF THEN DO alternative

Ouch.

Look at the documentation of the select statement (data step language).

``````select(mos);
when (3) do;
varpst = var(of mons1 - mons3);
meanpost = mean (of mons1 - mons3);
end;
.........
otherwise; /* if necessary */
end;``````

Next, I'd pack that into a macro:

``````%macro my_loop(max_mon);
data cpa (keep=reg lcd varpst meanpost mos);
set cpa_pst;
select(mos);
%do i = 3 %to &max_mon.;
when (&i.) do;
varpst = var(of mons1 - mons&i.);
meanpost = mean (of mons1 - mons&i.);
end;
%end;
otherwise; /* if necessary */
end;
%mend;

%my_loop(15)``````
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code

All Replies
Contributor
Posts: 44

## Re: IF THEN DO alternative

so are you saying you just needed the max of Mons instead of all the existing lines (i.i 1 to 15) ?
Solution
‎02-22-2017 11:40 AM
Super User
Posts: 10,626

## Re: IF THEN DO alternative

Ouch.

Look at the documentation of the select statement (data step language).

``````select(mos);
when (3) do;
varpst = var(of mons1 - mons3);
meanpost = mean (of mons1 - mons3);
end;
.........
otherwise; /* if necessary */
end;``````

Next, I'd pack that into a macro:

``````%macro my_loop(max_mon);
data cpa (keep=reg lcd varpst meanpost mos);
set cpa_pst;
select(mos);
%do i = 3 %to &max_mon.;
when (&i.) do;
varpst = var(of mons1 - mons&i.);
meanpost = mean (of mons1 - mons&i.);
end;
%end;
otherwise; /* if necessary */
end;
%mend;

%my_loop(15)``````
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Occasional Contributor
Posts: 17

## Re: IF THEN DO alternative

Awesome!  Thanks so much.  I don't think I've used the select statement in a data step before.

SAS Super FREQ
Posts: 4,277

## Re: IF THEN DO alternative

Read about the SELECT statement in the article "The SELECT statement in the SAS DATA step."

Occasional Contributor
Posts: 17

## Re: IF THEN DO alternative

Will do.  Thanks!

SAS Super FREQ
Posts: 4,277

## Re: IF THEN DO alternative

use the COLON to select all variables that match a specified prefix:

``````
data Want;
set Have;
array Y[*] MONS: ;
meanpst = mean(of Y[*]);
varpst = var(of Y[*]);
run;``````
Super User
Posts: 8,290

## Re: IF THEN DO alternative

[ Edited ]

Perhaps you don't need to do all of that work?

It looks to me that the variable MOS has the number of values you want to include. If the rest of the variables have missing values then the  MEAN() and VAR() statement will handle that automatically.  Try running this little test and see if there are any cases in your data where MOS is NOT the number of non-missing values in your list of data values.

``````data _null_;
set CPA_PST;
if mos ne n(of mons1-mons15) then do;
put (mos mons1-mons15) (=);
stop;
end;
run;``````

If not then you data step can just be this simple.

``````data want ;
set cpa_pst ;
if mos >= 3 then do;
varpst = var(of mons1-mons15);
meanpost=mean(of mons1-mons15);
end;
keep reg lcd varpst meanpost mos;
run;``````
🔒 This topic is solved and locked.