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

Hi all,

 

It feels like it has been a while since I came for your sage advice.

 

I have a macro that looks like the following: 

%macro yes(Exp);
data alldata_JB_052819;
set sub.alldata_jb_020819;
 PreResYr2nd6mo_&Exp =  PreResYr2nd6mo_&Exp + 1;
PostResYr1st6mo_&Exp = PostResYr1st6mo_&Exp + 1;
Prop&Exp = PostResYr1st6mo_&Exp/PreResYr2nd6mo_&Exp;
run;
%mend;
%yes(House);
%yes(Consume);
%yes(Durable);
%yes(Trans);
%yes(Health);
%yes(Insure);
%yes(Loan);
%yes(Tax);
%yes(Educa);
%yes(Gift);
%yes(Enter);
%yes(Recre);
%yes(FinPlan);
%yes(Legala);
%yes(AlcSpend);
%yes(ST2DENOM2);
%yes(ST2DENOM3);
%yes(ExpendTL);
%yes(FinPlSv);
%yes(IncomeTL);
%yes(ST2Oblig);

This macro is looping through each of these variables and then only creating the last variable in the new dataset. In this case, it is PropST2Oblig.

 

How do I make this macro loop through each of these variables and create a new variable (proportion of Post/Pre) for each instance?

 

For reference, the data set is quite large and in wide format. I want to create a proportion for each of the variables at each of the time intervals ( e.g., 12 1-month prop, 4 quarter-prop, 3 trimester-prop, etc.)

 

I am sure I could reduce the input somehow, but came looking for advice/what problem my macro has

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26
%macro yes(Exp);
data temp;
set sub.alldata_jb_020819;
 PreResYr2nd6mo_&Exp =  PreResYr2nd6mo_&Exp + 1;
PostResYr1st6mo_&Exp = PostResYr1st6mo_&Exp + 1;
Prop&Exp = PostResYr1st6mo_&Exp/PreResYr2nd6mo_&Exp;
run;
proc append base=temp new=all;
run;
%mend;

This is a simple way of getting everything into one data set, which I have cleverly named ALL., but you get a lot of missing values this way.

 

Probably a better way, which avoids the missing values problem:

 

%macro yes(Exp);
data alldata_JB_052819;
set sub.alldata_jb_020819;
%do i=1 %to %sysfunc(countw(&exp));
    %let thisexp=%scan(&exp,&i,%str( ));
 PreResYr2nd6mo_&thisExp =  PreResYr2nd6mo_&thisExp + 1;
PostResYr1st6mo_&thisExp = PostResYr1st6mo_&thisExp + 1;
Prop&thisExp = PostResYr1st6mo_&thisExp/PreResYr2nd6mo_&thisExp;
run;
%mend;
%yes(house consume durable) /* You type the rest of the variable names, I'm too lazy */
--
Paige Miller

View solution in original post

5 REPLIES 5
VDD
Ammonite | Level 13 VDD
Ammonite | Level 13

use a data step and do an append to add variable's to the original dataset.

 

PaigeMiller
Diamond | Level 26
%macro yes(Exp);
data temp;
set sub.alldata_jb_020819;
 PreResYr2nd6mo_&Exp =  PreResYr2nd6mo_&Exp + 1;
PostResYr1st6mo_&Exp = PostResYr1st6mo_&Exp + 1;
Prop&Exp = PostResYr1st6mo_&Exp/PreResYr2nd6mo_&Exp;
run;
proc append base=temp new=all;
run;
%mend;

This is a simple way of getting everything into one data set, which I have cleverly named ALL., but you get a lot of missing values this way.

 

Probably a better way, which avoids the missing values problem:

 

%macro yes(Exp);
data alldata_JB_052819;
set sub.alldata_jb_020819;
%do i=1 %to %sysfunc(countw(&exp));
    %let thisexp=%scan(&exp,&i,%str( ));
 PreResYr2nd6mo_&thisExp =  PreResYr2nd6mo_&thisExp + 1;
PostResYr1st6mo_&thisExp = PostResYr1st6mo_&thisExp + 1;
Prop&thisExp = PostResYr1st6mo_&thisExp/PreResYr2nd6mo_&thisExp;
run;
%mend;
%yes(house consume durable) /* You type the rest of the variable names, I'm too lazy */
--
Paige Miller
joebacon
Pyrite | Level 9

@PaigeMiller You crack me up. Thank you for taking the time to help me.

 

I attempted to implement the second solution, however, it is throwing the error: "ERROR 180-322: Statement is not valid or it is used out of proper order." when looping through the list of variables. House got inputted, but none of the other variables did.

 

This is the slightly modified code to include an "end" statement to the do-Loop.

 

%macro yes(Exp);
data alldata_JB_052819;
set sub.alldata_jb_020819;
%do i=1 %to %sysfunc(countw(&exp));
    %let thisexp=%scan(&exp,&i,%str( ));
 PreResYr2nd6mo_&thisExp =  PreResYr2nd6mo_&thisExp + 1;
PostResYr1st6mo_&thisExp = PostResYr1st6mo_&thisExp + 1;
Prop&thisExp = PostResYr1st6mo_&thisExp/PreResYr2nd6mo_&thisExp;
run;
%end;
%mend;
%yes(house consume durable Trans health Insure Loan Tax Educa Gift Enter REcre FinPlan Legala AlcSpend ST2DENOM2 ST2DENOM3 ExpendTl FinPlSv IncomeTL STOblig);

Any recommendations? 

Astounding
PROC Star
Move the RUN; statement to after the %END; statement.
joebacon
Pyrite | Level 9
Good catch. Silly mistake. Thank you. I must say that was rather Astounding...

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 5 replies
  • 1433 views
  • 5 likes
  • 4 in conversation