BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Char
Obsidian | Level 7

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!

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

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)

View solution in original post

7 REPLIES 7
anoopmohandas7
Quartz | Level 8
so are you saying you just needed the max of Mons instead of all the existing lines (i.i 1 to 15) ?
Kurt_Bremser
Super User

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)
Char
Obsidian | Level 7

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

Rick_SAS
SAS Super FREQ

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

Char
Obsidian | Level 7

Will do.  Thanks!

Rick_SAS
SAS Super FREQ

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;
Tom
Super User Tom
Super User

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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 2313 views
  • 2 likes
  • 5 in conversation