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!
Ouch.
Look at the documentation of the select statement (data step language).
Your code would look like
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)
Ouch.
Look at the documentation of the select statement (data step language).
Your code would look like
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)
Awesome! Thanks so much. I don't think I've used the select statement in a data step before.
Read about the SELECT statement in the article "The SELECT statement in the SAS DATA step."
Will do. Thanks!
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;
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;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.