I'm trying to name my columns _2013Q4 _2014Q1 etc. The code works if I use the commented out section towards the bottom but if I use the code with the _&Paid_Qtr., it says the IF statement is out of order.
%MACRO Create_Shell();
DATA Triangle;
DO n= 1 to &Cols.;
FORMAT
INC_MO MMDDYY10.;
INC_MO = INTNX("MONTH",MDY(MONTH(TODAY()),1,YEAR(TODAY())),n-&Cols.);
_2013Q3 = 0;
OUTPUT;
END;
RUN;
DATA Triangle;
SET Triangle;
%DO s=3 %TO &Cols. - 1 %BY 3;
%LET x = %EVAL(&Cols. - &s. + 1);
%LET t = %EVAL(&s. + 1);
DATA _NULL_;
FORMAT
PAID_QTR YYQ.;
PAID_QTR = INTNX("MONTH",MDY(MONTH(TODAY()),1,YEAR(TODAY())) -1,&s. - &Cols.);
PUT PAID_QTR=;
PAID_QTR2= PUT(PAID_QTR,YYQ.);
PUT PAID_QTR2=;
CALL SYMPUTX('PAID_QTR',PAID_QTR2);
RUN;
%PUT &=PAID_QTR;
IF &x. > _N_ THEN
_&PAID_QTR. = 0;
ELSE _&PAID_QTR. = .;
/* IF &x. > _n_ THEN */
/* _&t. = 0;*/
/* ELSE _&t. = .;*/
%END;
RUN;
%MEND Create_Shell;
OPTIONS MPRINT MLOGIC;
%Create_Shell;
OPTIONS NOMPRINT NOMLOGIC;
Before you start writing a macro to generate SAS code figure out what SAS code you want to generate.
I looks like you are playing with the same triangle matrix generating step, but now you want to generate variable names that contain dates in them. So first figure out what code you want to generate. As I said on your other question you don't need macro code to generate your matrix. Just use an ARRAY statement. If you want to make the variable names dynamic then use a macro variable to hold the list of names. You can use a data step to generate the macro variable.
Let's say you want to generate these variables:
array cols Y2018Q4 Y2019Q1 Y2019Q2 ;
You could run this data step to generate a macro variable.
data _null_;
length varlist $1000;
do offset=0 to &cols -1 ;
date = intnx('qtr',today(),offset);
varlist=catx(' ',varlist,cats('Y',put(date,yyq.)));
end;
call symputx('varlist',varlist);
run;
Then your ARRAY statement can be:
array cols &varlist;
&Cols. = 60 currently.
where is the datastep for this part?
RUN;
%PUT &=PAID_QTR;
IF &x. > _N_ THEN
_&PAID_QTR. = 0;
ELSE _&PAID_QTR. = .;
/* IF &x. > _n_ THEN */
/* _&t. = 0;*/
/* ELSE _&t. = .;*/
%END;
RUN;
it is apart of the DATA Triangle;
The first RUN statement ends the DATA _NULL_ and then the RUN at the bottom the code you pasted is supposed to end the DATA Triangle data step.
Thanks,
Paul
Nope, when a data step encounters another DATA statement that serves as a RUN and closes the first step. Your RUN statements are incorrectly set and you cannot have nested DATA Steps.
This is more clear when you format your code.
%MACRO Create_Shell();
DATA Triangle;
DO n=1 to &Cols.;
FORMAT INC_MO MMDDYY10.;
INC_MO=INTNX("MONTH", MDY(MONTH(TODAY()), 1, YEAR(TODAY())), n-&Cols.);
_2013Q3=0;
OUTPUT;
END;
RUN;
DATA Triangle;
SET Triangle;
%DO s=3 %TO &Cols. - 1 %BY 3;
%LET x = %EVAL(&Cols. - &s. + 1);
%LET t = %EVAL(&s. + 1);
DATA _NULL_; *ends data triangle step;
FORMAT PAID_QTR YYQ.;
PAID_QTR=INTNX("MONTH", MDY(MONTH(TODAY()), 1, YEAR(TODAY())) -1,
&s. - &Cols.);
PUT PAID_QTR=;
PAID_QTR2=PUT(PAID_QTR, YYQ.);
PUT PAID_QTR2=;
CALL SYMPUTX('PAID_QTR', PAID_QTR2);
RUN; *ends _null_ step;
%PUT &=PAID_QTR;
IF &x. > _N_ THEN _&PAID_QTR.=0; *open invalid data step code;
ELSE _&PAID_QTR.=.;
/* IF &x. > _n_ THEN */
/* _&t. = 0;*/
/* ELSE _&t. = .;*/
%END;
RUN;
%MEND Create_Shell;
OPTIONS MPRINT MLOGIC;
%Create_Shell;
OPTIONS NOMPRINT NOMLOGIC;
@pchappus wrote:
it is apart of the DATA Triangle;
The first RUN statement ends the DATA _NULL_ and then the RUN at the bottom the code you pasted is supposed to end the DATA Triangle data step.
Thanks,
Paul
Okay that makes since, I need to figure out a way to have the loop create the column names without doing a data null step.
For some reason, when ever I paste my code it takes away all my formatting I have in the program.
Use indentation to format your code to make it clearer. I like the set the indentation of macro statements independently from the indentation of the actual SAS code that the macro is generating.
%macro create_shell();
data triangle;
do n= 1 to &cols.;
format inc_mo mmddyy10.;
inc_mo = intnx("month",mdy(month(today()),1,year(today())),n-&cols.);
_2013q3 = 0;
output;
end;
run;
data triangle;
set triangle;
%do s=3 %to &cols. - 1 %by 3;
%let x = %eval(&cols. - &s. + 1);
%let t = %eval(&s. + 1);
data _null_;
format paid_qtr yyq.;
paid_qtr = intnx("month",mdy(month(today()),1,year(today())) -1,&s. - &cols.);
put paid_qtr=;
paid_qtr2= put(paid_qtr,yyq.);
put paid_qtr2=;
call symputx('paid_qtr',paid_qtr2);
run;
%put &=paid_qtr;
if &x. > _n_ then_&paid_qtr. = 0;
else _&paid_qtr. = .;
%end;
run;
%mend create_shell;
That way it is easy to see that you have two line data step that does nothing.
data triangle;
set triangle;
which will end if the %DO loop runs at least once and generates other steps.
And also an IF statements detached from any data step at the end of your %DO loop.
if &x. > _n_ then_&paid_qtr. = 0;
else _&paid_qtr. = .;
and an extra RUN statement after the %DO loop.
Before you start writing a macro to generate SAS code figure out what SAS code you want to generate.
I looks like you are playing with the same triangle matrix generating step, but now you want to generate variable names that contain dates in them. So first figure out what code you want to generate. As I said on your other question you don't need macro code to generate your matrix. Just use an ARRAY statement. If you want to make the variable names dynamic then use a macro variable to hold the list of names. You can use a data step to generate the macro variable.
Let's say you want to generate these variables:
array cols Y2018Q4 Y2019Q1 Y2019Q2 ;
You could run this data step to generate a macro variable.
data _null_;
length varlist $1000;
do offset=0 to &cols -1 ;
date = intnx('qtr',today(),offset);
varlist=catx(' ',varlist,cats('Y',put(date,yyq.)));
end;
call symputx('varlist',varlist);
run;
Then your ARRAY statement can be:
array cols &varlist;
I think I will eventually end up going the array route but using this as a learning opportunity to do it the more complicated way.
Thanks for the help!
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.