Creating different numbers of macro variables

Solved
Frequent Contributor
Posts: 77

Creating different numbers of macro variables

What I have:

%let year_cohort = 03; /* it needs to have a single leading 0 if less than 10 */

%let AY_start = &year_cohort +1;

%let AY_end = &year_cohort + 6;

%let AY_YEAR1=04;/* it needs to have a single leading 0 if less than 10 */

%let AY_YEAR2=05;

%let AY_YEAR3=06;

%let AY_YEAR4=07;

%let AY_YEAR5=08;

%let AY_YEAR6=09;

What I want (except, working):

%let year_cohort = 03;

%let num_of_years = 6;

%let AY_start = &year_cohort + 1;

%let AY_end = &year_cohort + &num_of_years;

and then I would like the AY_YEARi to be created based on the number contained in the &num_of_years variable (in this case, 6).

Accepted Solutions
Solution
‎05-28-2013 01:19 PM
Super User
Posts: 23,747

Re: Creating different numbers of macro variables

I'd use a data _null_ step with a do loop to create them:

%let year_cohort=01;

%let num_years=10;

data _null_;

start=&year_cohort;

call symput('ay_start', put(start+1, z2.));

call symput('ay_end', put(start+&num_years, z2.));

year_count=1;

do i=1 to &num_years;

call symput("ay_year"||compress(put(i, 8.)), put(start+i, z2.));

end;

run;

*Check macro variables are created ok;

%put &ay_start;

%put &ay_end;

%put &ay_year1;

%put &ay_year3;

%put &ay_year6;

%put &ay_year9;

All Replies
Solution
‎05-28-2013 01:19 PM
Super User
Posts: 23,747

Re: Creating different numbers of macro variables

I'd use a data _null_ step with a do loop to create them:

%let year_cohort=01;

%let num_years=10;

data _null_;

start=&year_cohort;

call symput('ay_start', put(start+1, z2.));

call symput('ay_end', put(start+&num_years, z2.));

year_count=1;

do i=1 to &num_years;

call symput("ay_year"||compress(put(i, 8.)), put(start+i, z2.));

end;

run;

*Check macro variables are created ok;

%put &ay_start;

%put &ay_end;

%put &ay_year1;

%put &ay_year3;

%put &ay_year6;

%put &ay_year9;

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

Thank you both! The first I tried worked as intended, though I may need to explore the second for another piece of this puzzle at a later date.

Thank you again!

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

What does the year_count = 1; in the middle of the data _null_ step do?

Super User
Posts: 23,747

Re: Creating different numbers of macro variables

nothing...you can delete it. I was originally going to use it as a counter but realized that I could use the i instead.

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

Can I create one macro variable that is essentially the concatenation of those created in the do loop?

I want to replace this:

array Grad_year {1:6} \$ ("&AY_YEAR1" "&AY_YEAR2" "&AY_YEAR3" "&AY_YEAR4" "&AY_YEAR5" "&AY_YEAR6");

With something like this:

Super User
Posts: 23,747

Re: Creating different numbers of macro variables

You should be able to use the start and end variables instead.

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

Thank you, but it isn't working as expected.

Here is my input:

%let year_cohort=03;

%let num_years=6;

data _null_;

start=&year_cohort;

call symput('ay_start', put(start+1, z2.));

call symput('ay_end', put(start+&num_years, z2.));

do i=1 to &num_years;

call symput("ay_year"||compress(put(i, 8.)), put(start+i, z2.));

end;

run;

data test;

run;

and here is the log:

391  %let year_cohort=03;

392  %let num_years=6;

393

394  data _null_;

395      start=&year_cohort;

396      call symput('ay_start', put(start+1, z2.));

397      call symput('ay_end', put(start+&num_years, z2.));

398

399      do i=1 to &num_years;

400          call symput("ay_year"||compress(put(i, 8.)), put(start+i, z2.));

401      end;

402  run;

NOTE: DATA statement used (Total process time):

real time           0.00 seconds

cpu time            0.00 seconds

403

404  data test;

WARNING: Partial value initialization of the array Grad_year.

406  run;

NOTE: The data set WORK.TEST has 1 observations and 6 variables.

NOTE: DATA statement used (Total process time):

real time           0.00 seconds

cpu time            0.00 seconds

And the dataset is as follows:

4-9....

It's reconciling to 4 -9 instead of 04-09 (in this case).

I'll keep trying things along those lines. Thank you again!

ETA: I've also tried using spaces ( &ay_start - &ay_end ) and quotes ("&ay_start" - "&ay_end") with different, although still not working, results.

Super User
Posts: 23,747

Re: Creating different numbers of macro variables

Take a look at your original question, that was what you specified, ie ay_year1 ay_year2, not ay_year01 vs ay_year02

I think you're confusing macro variable names and values.

There is a mistake though, this should be as follows.

You may want to go back to the start and describe more what your'e doing though. Because you probably could just do the following instead:

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

You're right (of course) - I want macro variable AY_Year1 to have a value of 04 (in this case).

So in the above table that I inserted, Grad_year1 is almost correct (I want it to say 04, not 4), but Grad_year2 is incorrect (-9, it should say 05).

I suspect what I'm doing is just approached the wrong way to begin with. I've been using SAS for less than 6 months, and I haven't had much time to actually learn what I am doing, just "Googling" this and that, etc.

This:

does the same thing as this:

%put &ay_year1 = 04

Super User
Posts: 23,747

Re: Creating different numbers of macro variables

Hi Greg,

Can you go way back and explain what you're trying to do. I don't think you need macro's at all, but until I know more I can only guess.

Super User
Posts: 8,114

Re: Creating different numbers of macro variables

What is it that you really want to do? Do you want to put values into datasets or create macro variables?

Usually the goal of SAS programming is to manipulate data and macro programming is resorted to when more flexibility is needed that what SAS programming can do.

For example you seem concerned that the numeric variable GRAD_YEAR1 had a 4 instead of 04, but since it is a numeric variable there is no difference.  Perhaps you just want to add a format such as Z2. to the variable so that numbers less than 10 print with a leading zero?  Perhaps you would rather have GRAD_YEAR1  be defined as a character variable instead? Then you could store '04' into it instead of '4' and it would actually be a different value.

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

Okay, I was given the following with the idea of only changing two variables - the starting year (year_cohort) and the number of years.  The comments below are the comments as I was given them.

%let year_cohort=03;/*the fall semester belongs to academic year + 1*/

%let AY_start = &year_cohort + 1;/*The fall academic year*/

%let AY_end  =  &year_cohort + 6;

%let AY_YEAR1=04;

%let AY_YEAR2=05;

%let AY_YEAR3=06;

%let AY_YEAR4=07;

%let AY_YEAR5=08;

%let AY_YEAR6=09;

by major LVL_DEGREE;

if a;

GRADUATE_DATE=datepart(GRAD_DATE);/*ORACLE DATES HAVE TIME COMPONENTS TO THEM. THIS SAS FUNCTION JUST TAKES THE DATE PART.*/

/*An array of character values and not variable names. Hence, the \$ and parenthesis around the list*/

array Grad_year {1:6} \$ ("&AY_YEAR1" "&AY_YEAR2" "&AY_YEAR3" "&AY_YEAR4" "&AY_YEAR5" "&AY_YEAR6");

%MACRO CREATE_VAR(START,END);

%DO I=&START %TO &END;

/*COMES FROM CIP FILE*/

College_&I= College_C; CIP_&I=CIP; Degree1_C&I=DEGREE1_C;Degree_&I=DEGREE; Lvl_&I=LVL_C;

end;

%END;

%MEND CREATE_VAR;

%CREATE_VAR(1,6);

RUN;

-----------------

So you can see the questions I have above, and where I am trying to go with them. Sorry about not providing this at the beginning. I wasn't sure sharing this much would be helpful.

Again, the idea is to only have to change year_cohort= and to add a num_years variable to set the number of years, and have everything else fall into place from there.

Super User
Posts: 8,114

Re: Creating different numbers of macro variables

I assume that the reason you were originally concentrating on the the leading zeros for the years is because the variable ACADEMIC_YEAR from you input dataset is character instead of numeric.  Why not just convert it to a number and stop worrying about the leading zeros?

Why do you need the cohort datasets?  Why not just create a single dataset with a cohort variable?

Is YEAR_COHORT the only input or is the upper bound of 6 years also an input variable?

Do you have to deal with century boundaries?  What if YEAR_COHORT was 98 (ie 1998)?

data want ;

by major LVL_DEGREE;

if a;

cohort = input(academic_year,2.) - &Year_Cohort + 1;

if cohort < 1 or cohort > 6 then delete;

/* You could have the other reformatting things here */

run;

Then if you really want to split it into 6 separate datasets then you could generate code for that.

Frequent Contributor
Posts: 77

Re: Creating different numbers of macro variables

I think the idea is to track the person overtime (again, I was given this to "explore").

So a dataset like so:

001     09/FA     other fields/variables

001     10/FA     other fields/variables

001     11/FA     other fields/variables

would become:

001 09/FA     (09/FA related variables)     10/FA (related variables)     11/FA (related variables)

I don't foresee having to deal with century boundaries at this time, 10 years seems to be the most we would deal with at any one time.

It's not that I want to split into 6 years, I want to split into n years, where n is set by the user in a macrovariable (num_years) at the beginning of the program (along with the year_cohort).

🔒 This topic is solved and locked.