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

Hi All, 

Hopefully, someone can help me, I've been searching the forums all day for a solution...

I am trying to change a %LET variable within a maco's DO loop, using %eval. However i only want the %eval line to work under a certain condition, unfortunately, the %eval statement is always operating. I've tried to use %symput but I can't get that to work. 

I've pasted an extract of code below. The issues is the variable j, which is used as an index variable. Essentially i have two types variables: Building_Claim_Cause_0 and Contents_Claim_Cause_0   (both of which go up to 4, i.e Contents_Claim_Cause_1, Contents_Claim_Cause_2...)

I need to combine these two variables into one variable (HOMELOSSTx) where the buildings and contents claim variables. i.e if there is a value in Building_Claim_Cause_0, then let HOMELOSST0 equal it, and if there is a value in Contents_Claim_Cause_0  as well let HOMELOSST1 equal it. I am using j to as the index value for HOMELOSS and k as the index value between buildings and contents claims, and i as the index value between 0 to 4 for the buildings/contents claims).

 

 

 

%MACRO CLAIMS(MAXNUM);
	/*INTIALISE CLAIMS VARIABLES*/
	
	%LET i = 0;   	/*CYCLE THROUGH THE Specific_ItemX VARIABLE. IF THERE IS AN ITEM THEN SPECIFIED ITEM COVER HAS BEEN SELECTED*/
	%LET j = 0; 	/*CLAIM FOUND COUNT - WE ARE COLLAPSING THE BUILDING CLAIM VARIABLES AND CONTENTS CLAIM VARIABLES INTO ONE ONE CLAIM VARIABLE*/
	
	%DO %UNTIL (&i. = &MAXNUM.*2+2);	/*we have 5 potential bld or cnt claims. count starts at 0 hence maxnum is 4*/
		FORMAT CLAIMCOVE&i. FMT_CLAIMCOVER.;
		FORMAT HOMELOSST&i. FMT_HOMELOSSTY.;
		FORMAT HMELOSOTT&i. FMT_HMELOSOTTY.;
		FORMAT DATEOFLOS&i. DDMMYY8.;
		FORMAT PROPCLAIM&i. FMT_PROPCLAIMX.;
		FORMAT AMTPAIDOS&i 	best32.;

		CLAIMCOVE&i. = 0; 		/*Was it a contents or building incident?*/
		HOMELOSST&i. = 0; 		/*What type of incident was it?*/
		HMELOSOTT&i. = 0; 		/*Please specify:*/
		DATEOFLOS&i. = .; 		/*When did the incident occur?*/			 
		PROPCLAIM&i. = 999;	/*Did you make a claim?*/
		AMTPAIDOS&i. = .;		/*How much was paid out (or you have received so far) for this claim?*/

		%LET i = %eval(&i.+1);
	%END;
	
	%LET i = 0;/*reset counter*/
	
	%DO %UNTIL (&i. = &MAXNUM. +1);
		%LET k = 0;/*reset claim type counter (bld or cts)*/
		IF CLAIMLAST5 = 1 THEN DO;
			%DO k = 1 %TO 2;
			
				%IF &k. = 1 %THEN %DO; 
					
					%LET QZ_CLMType = 	Building_Claim_Cause_		;
					%LET QZ_CLMDate = 	Building_Claim_QuteDate_	;
					%LET QZ_CLMLoc	=	Building_Claim_Location_ 	;
					%LET QZ_CLMAmt	=	Building_Claim_Amount_ 		; 
				%END;
				%ELSE %DO;
					
					%LET QZ_CLMType = 	Contents_Claim_Cause_		;
					%LET QZ_CLMDate = 	Contents_Claim_QuteDate_	;
					%LET QZ_CLMLoc	=	Contents_Claim_Location_ 	;
					%LET QZ_CLMAmt	=	Contents_Claim_Amount_ 		;
				%END;
				
				SELECT (&QZ_CLMType.&i.);
					WHEN ("", "N") DO;
					END; /* DO NOTHING*/
					OTHERWISE DO;
						IF &k. = 1 THEN DO; 
							CLAIMCOVE&j. = 1; 		/*Was it a contents or building incident?*/
						END;
						ELSE DO;
							CLAIMCOVE&j. = 2; 		/*Was it a contents or building incident?*/
						END;
						
						SELECT (&QZ_CLMType.&i.);  
								
							WHEN ("Flood Damage") 			HOMELOSST&j. = 1; 	/*Flood*/
							OTHERWISE 						HOMELOSST&j. = 9; 												/*Other*/
						END;
						
						IF HOMELOSST&j. < 9 THEN HMELOSOTT&j. = 0;
						ELSE DO;
							SELECT (&QZ_CLMType.&i.);
								WHEN ("Additional Expenses") 	HMELOSOTT&j. = 1; 			/*Additional Expenses*/							
								OTHERWISE 						HMELOSOTT&j. = 99;
	
							END; /*HMELOSOTTY - CLAIM CAUSE CODES*/							
						END;  
						
						DATEOFLOS&j. = &QZ_CLMDate.&i.; 	/*When did the incident occur?*/			 
						SELECT (&QZ_CLMLoc.&i.);
							WHEN ("N") PROPCLAIM&j. = 3;
							WHEN ("Y") PROPCLAIM&j. = 1;
							OTHERWISE PROPCLAIM&j. 	= 99;
						END;											
						AMTPAIDOS&j. = &QZ_CLMAmt.&i.;		/*How much was paid out (or you have received so far) for this claim?*/
						%LET j = %eval(&j.+ 1);				/*This is the index value for claim variable we are using.*/
					END; /*OTHERWISE DO;*/
				END; /*SELECT (&QZ_CLMType.&i.);*/
																		
			%END; /*LOOP ACROSS Building_Claim_QuteDate_&i. and  AND Contents_Claim_Cause_&i.*/
																	
		END; /*IF CLAIMLAST5 = 1 THEN DO;*/
		%LET i = %eval(&i.+ 1);		
	%END;
%MEND; /*CLAIMS*/

data toto ;
set RAWDATA.QZDATA (KEEP = Had_Any_Building_Claims Had_Any_Contents_Claims
							Building_Claim:	Contents_Claim:
					/*OBS = 12*/);
	
/*Have you, or anyone living at your property had any incidents or made a home insurance claims in the last five years? (in this or another property)*/
	IF Had_Any_Building_Claims = "" OR Had_Any_Contents_Claims = "" THEN CLAIMLAST5 = 0;
	ELSE IF Had_Any_Building_Claims = "N" AND Had_Any_Contents_Claims = "N" THEN CLAIMLAST5 = 0;
	ELSE CLAIMLAST5 = 1;	
	
	%CLAIMS(MAXNUM = 4);  
RUN;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

You're making a fundamental mistake in the way that you treat macro language.  Macro language does not process your data.  Instead, it is supposed to generate SAS language statements.  Those are what process your data.  To give you an example, here is a rewrite of the beginning of your code:

 

%macro claims (maxnum);

   %local j;

   %let j = %eval(2 * &maxnum + 2);

   format claimcove1 - claimcove&j fmt_claimcover.;

   format homelosst1 - homelosst&j fmt_homelossty.;

   ...

   format amtpaidos1 - amtpaidos&j  best32.;

 

   array claimcove {&j};

   array homelosst {&j};

   ...

   array propclaim {&j};

   array amtpaidos {&j};

 

   do _i_ = 1 to &j;

      claimcove{_i_} = 0;

      homelosst {_i_} = 0;

      ...

      propclaim{_i_} = 999;

   end;

 

 

You need to use macro language to generate SAS language statements, and to do that you need to have a firm idea of what the SAS statements should look like.  That part becomes a little cloudy in the second half of your macro.

View solution in original post

3 REPLIES 3
ballardw
Super User

@Squibbles wrote:

Hi All, 

 

 Essentially i have two types variables: Building_Claim_Cause_0 and Contents_Claim_Cause_0   (both of which go up to 4, i.e Contents_Claim_Cause_1, Contents_Claim_Cause_2...)

I need to combine these two variables into one variable (HOMELOSSTx) where the buildings and contents claim variables. i.e if there is a value in Building_Claim_Cause_0, then let HOMELOSST0 equal it, and if there is a value in Contents_Claim_Cause_0  as well let HOMELOSST1 equal it. I am using j to as the index value for HOMELOSS and k as the index value between buildings and contents claims, and i as the index value between 0 to 4 for the buildings/contents claims).

 


It may help to provide a little example data start and end. But it looks like a few arrays would handle this without any macro logic needed at all, at least for that look at pairs(?) of values and assign a third.

Astounding
PROC Star

You're making a fundamental mistake in the way that you treat macro language.  Macro language does not process your data.  Instead, it is supposed to generate SAS language statements.  Those are what process your data.  To give you an example, here is a rewrite of the beginning of your code:

 

%macro claims (maxnum);

   %local j;

   %let j = %eval(2 * &maxnum + 2);

   format claimcove1 - claimcove&j fmt_claimcover.;

   format homelosst1 - homelosst&j fmt_homelossty.;

   ...

   format amtpaidos1 - amtpaidos&j  best32.;

 

   array claimcove {&j};

   array homelosst {&j};

   ...

   array propclaim {&j};

   array amtpaidos {&j};

 

   do _i_ = 1 to &j;

      claimcove{_i_} = 0;

      homelosst {_i_} = 0;

      ...

      propclaim{_i_} = 999;

   end;

 

 

You need to use macro language to generate SAS language statements, and to do that you need to have a firm idea of what the SAS statements should look like.  That part becomes a little cloudy in the second half of your macro.

Squibbles
Fluorite | Level 6

ok thanks both. 

i'll look into arrays & rethink the structure. 

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
  • 3 replies
  • 2799 views
  • 3 likes
  • 3 in conversation