Do loop + macro

Accepted Solution Solved
Reply
Contributor
Posts: 24
Accepted Solution

Do loop + macro

Hello, 

 

I try to write a program to find out age at July 1 of each year specified.  

I am having a problem to find out what is wroing with my program.

 

==============================================

data new_data;
set old_data;
array age(5) age06-age15;
%let sYr=2006;
%let eYr=2015;
do year =&sYr to &eYr;
%let sDate="1Jul&year"d;

 

age(year) = floor((intck('month',dob,&sDate)-(1<day(dob)))/12);
end;
run;

===================================================

 

I got warnign and error messages:

WARNING: Apparent symbolic reference YEAR not resolved.
ERROR: Invalid date/time/datetime constant "1Jul&year"d.

 

I can tell something is wroing especially with 'sDate'.  

 

Could anybody tell me why I got these messages and how I can fix this please? 

 

Thank you, 

 

YI

 

 

 

 

 

 

 


Accepted Solutions
Solution
‎09-13-2017 08:22 AM
Super User
Posts: 13,321

Re: Do loop + macro


Yoko wrote:
Suggested program==========================================

data new_data;
set old_data;
array age(10) age06-age15;
do year =2006 to 2015;
age(year) = floor((intck('month',dob,mdy(7, 1, year))-(1
OUTPUT;
end;
run;

error messages ===============================================
ERROR: Array subscript out of range at line 137 column 2.


When define an array as you did the array index expects values of 1 to 10; age(1) for example. If you want to use actual values of year such as 2006 then you need to define the array boundary limits:

data junk;
   array a (2006:2015) age06-age15;
   do year=2006 to 2015;
      a(year) = <calculation>;
   end;
run;

 

 

View solution in original post


All Replies
Super User
Posts: 23,296

Re: Do loop + macro

DO NOT USE A MACRO.

 

There's no need for a macro here, use data step variables and get that working first, and then you can add a macro loop after, if required.

 

Since you're trying to add records, you need an OUTPUT statement inside your do loop to add the new rows.

 

data new_data;
set old_data;
array age(5) age06-age15;


do year =2006 to 2015;

 
age(year) = floor((intck('month',dob,mdy(7, 1, year))-(1<day(dob)))/12);

OUTPUT;

end;
run;
Contributor
Posts: 24

Re: Do loop + macro

Hello,



Thank you for your reply.

I tried your suggestion.

But, I still have this error message:



ERROR: Array subscript out of range at line 137 column 2.



Sorry, but I'm new to SAS and not sure what this means.

Would you have any other suggestions?



Thank you,



Yoko




Super Contributor
Super Contributor
Posts: 266

Re: Do loop + macro

[ Edited ]

I think the array out of subscript error is becasue you are putting ten years (2006 to 2015) into a 5 position array.  Try array age(10).

 

 

Contributor
Posts: 24

Re: Do loop + macro

Yes, that was my error.  I have 10 in that place now. 

 

Thakn you!

 

Yoko

PROC Star
Posts: 1,584

Re: Do loop + macro

Your code suggests understanding of the entire macro compliation and execution is wrong particularly when dealing with timing. Have you tried without macro in the first place?

Contributor
Posts: 24

Re: Do loop + macro

Hello,



Just before your message, I received a message from somebody.

She suggests that I do not use macro too.



I tried her suggestion, but I still got an error message (different one).



Suggested program==========================================



data new_data;
set old_data;
array age(10) age06-age15;


do year =2006 to 2015;


age(year) = floor((intck('month',dob,mdy(7, 1, year))-(1
OUTPUT;

end;
run;





error messages ===============================================

ERROR: Array subscript out of range at line 137 column 2.





I already asked her, but if you have any other suggestions, I appreciate it.




Thank you,



Yoko


Solution
‎09-13-2017 08:22 AM
Super User
Posts: 13,321

Re: Do loop + macro


Yoko wrote:
Suggested program==========================================

data new_data;
set old_data;
array age(10) age06-age15;
do year =2006 to 2015;
age(year) = floor((intck('month',dob,mdy(7, 1, year))-(1
OUTPUT;
end;
run;

error messages ===============================================
ERROR: Array subscript out of range at line 137 column 2.


When define an array as you did the array index expects values of 1 to 10; age(1) for example. If you want to use actual values of year such as 2006 then you need to define the array boundary limits:

data junk;
   array a (2006:2015) age06-age15;
   do year=2006 to 2015;
      a(year) = <calculation>;
   end;
run;

 

 

Super Contributor
Super Contributor
Posts: 266

Re: Do loop + macro

[ Edited ]

To recap all of the above (because it is a good learning experience for me)  this code:

 

data birthdates;
   input dob date9.;
datalines;
01jan1962
26oct1973
17aug2000
05may1999
;
run;

data age_at_years;
	set birthdates;
	array age(2006:2015) age06-age15;
		do year = 2006 to 2015;
			age(year) = floor((intck('month',dob,mdy(7, 1, year))-(1<day(dob)))/12);
		end;
	drop year;
run;

produces a table that looks like:

 

                     
                     
dob age06 age07 age08 age09 age10 age11 age12 age13 age14 age15
731 44 45 46 47 48 49 50 51 52 53
5047 32 33 34 35 36 37 38 39 40 41
14839 5 6 7 8 9 10 11 12 13 14
14369 7 8 9 10 11 12 13 14 15 16

 

Cool.

 

Edit:

 

1.  Standard admonition about storing calculated values.

 

2. @ballardw I think I learn from your every post. +1

Contributor
Posts: 24

Re: Do loop + macro

Thank you!

I appreciate that you added 'drop year;' .



Yoko


Contributor
Posts: 24

Re: Do loop + macro

Thank you, it worked!

Yoko


☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 10 replies
  • 218 views
  • 1 like
  • 5 in conversation