DATA Step, Macro, Functions and more

Creating Trimester using data step

Accepted Solution Solved
Reply
Super Contributor
Posts: 266
Accepted Solution

Creating Trimester using data step

Hi All,

I have created a programe to create table for trimester. 

I m looking for ur help/suggestion if that can be bit sort/small and with less complex.

Code:


data test;
x="01jan2016"d;
if MONTH(INTNX("MONTH",x,-1))<=4 then do ;
DO I= MONTH(INTNX("MONTH",x,-1)) to 1 by -1;
do j= i to 1 by -1;
TIME=cats("T1_M",i,"_",Year(INTNX("MONTH",x,-1)));
YRMO=INPUT(PUT(INTNX("MONTH",x,-MONTH(INTNX("MONTH",x,-1))+j-1),YYMMN6.),6.);
output;
end;
end;
end;

if 4< MONTH(INTNX("MONTH",x,-1))<=8 then do ;
DO I= MONTH(INTNX("MONTH",x,-1)) to 1 by -1;

if i <=4 then do;
do j= i to 1 by -1;
TIME=cats("T1_M",i,"_",Year(INTNX("MONTH",x,-1)));
YRMO=INPUT(PUT(INTNX("MONTH",x,-MONTH(INTNX("MONTH",x,-1))+j-1),YYMMN6.),6.);
output;
end;
end;
else do;
do j= i to 5 by -1;
TIME=cats("T2_M",i-4,"_",Year(INTNX("MONTH",x,-1)));
YRMO=INPUT(PUT(INTNX("MONTH",x,-MONTH(INTNX("MONTH",x,-1))+j-1),YYMMN6.),6.);
output;
end;
end;
end;
end;
/****************/

if 8< MONTH(INTNX("MONTH",x,-1))<=12 then do ;
DO I= MONTH(INTNX("MONTH",x,-1)) to 1 by -1;

if i <=4 then do;
do j= i to 1 by -1;
TIME=cats("T1_M",i,"_",Year(INTNX("MONTH",x,-1)));
YRMO=INPUT(PUT(INTNX("MONTH",x,-MONTH(INTNX("MONTH",x,-1))+j-1),YYMMN6.),6.);
output;
end;
end;
else if 4< i <=8 then do;
do j= i to 5 by -1;
TIME=cats("T2_M",i-4,"_",Year(INTNX("MONTH",x,-1)));
YRMO=INPUT(PUT(INTNX("MONTH",x,-MONTH(INTNX("MONTH",x,-1))+j-1),YYMMN6.),6.);
output;
end;
end;
else if 8< i <=12 then do;
do j= i to 9 by -1;
TIME=cats("T3_M",i-8,"_",Year(INTNX("MONTH",x,-1)));
YRMO=INPUT(PUT(INTNX("MONTH",x,-MONTH(INTNX("MONTH",x,-1))+j-1),YYMMN6.),6.);
output;
end;
end;

end;
end;


run;

 

Thanks in advance


Accepted Solutions
Solution
‎02-22-2016 05:07 AM
Super User
Posts: 7,766

Re: Creating Trimester using data step

data _null_;
date = date();
date = intnx('month',date,-1);
call symput('year',substr(put(year(date),z4.),3,2));
startmonth = int((month(date)-1)/4) * 4 +1;
call symput('startmonth',strip(put(startmonth,2.)));
call symput('endmonth',strip(put(month(date),2.)));
run;

data want1;
do month = &startmonth to &endmonth;
  month_print = put(mdy(month,1,&year),monyy5.);
  t = int((month-1)/4) + 1;
  if &startmonth = 1 and &endmonth = 12 /* whole year */
  then stopmonth = 4;
  else stopmonth = min(4,&endmonth-(t-1)*4);
  do m = mod(month-1,4)+1 to stopmonth;
    period = 'T'!!put(t,1.)!!'M'!!put(m,1.);
    output;
  end;
end;
run;

proc sort
  data=want1
  out=want(keep=month_print period)
;
by period month;
run;

To get the whole year, add

%let startmonth=1;

before the data want1 step

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

View solution in original post


All Replies
Super User
Posts: 7,766

Re: Creating Trimester using data step

Could you please state your logic in simnple language (ie date range of a to b is trimester 1, c to d is trimester 2, and so on)

 

Also use the code entry window (the "run SAS" symbol) to post SAS Code

 

And use proper formatting to make your code readable. As is, it is causing eyesores.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super Contributor
Posts: 266

Re: Creating Trimester using data step

[ Edited ]
Posted in reply to KurtBremser

LOGIC is

if i will run the programe IN JAN-2016 then i will get output as

MONTH       PERIOD

JAN15         T1M1
JAN15         T1M2
FEB15         T1M2
JAN15         T1M3
FEB15         T1M3
MAR15        T1M3
JAN15         T1M4
FEB15         T1M4
MAR15        T1M4
APR15         T1M4
MAY15       T2M1
MAY15      T2M2
JUN15      T2M2
MAY15    T2M3
JUN15    T2M3
JUL15    T2M3
MAY15    T2M4
JUN15    T2M4
JUL15    T2M4
AUG15    T2M4
SEP15    T3M1
SEP15    T3M2
OCT15    T3M2
SEP15    T3M3
OCT15    T3M3
NOV15    T3M3
SEP15    T3M4
OCT15    T3M4
NOV15    T3M4
DEC15    T3M4

I USED X AS TODAY() TO DO CROSS CHECK FOR EVERY MONTH'S OUTPUT
CODE:

 

 

DATA TEST;
X="01JAN2016"D;
/******FOR JAN TO APR MONTH******/
IF MONTH(INTNX("MONTH",X,-1))<=4 THEN
DO ;
               DO I= MONTH(INTNX("MONTH",X,-1)) TO 1 BY -1;
                         DO J= I TO 1 BY -1;
                                TIME=CATS("T1_M",I,"_",YEAR(INTNX("MONTH",X,-1)));
                                YRMO=INPUT(PUT(INTNX("MONTH",X,-MONTH(INTNX("MONTH",X,-1))+J-1),YYMMN6.),6.);
                                OUTPUT;
                        END;
              END;
END;

/********FOR MAY TO AUG MONTH********/
IF 4< MONTH(INTNX("MONTH",X,-1))<=8 THEN
DO ;
                    DO I= MONTH(INTNX("MONTH",X,-1)) TO 1 BY -1;
                               IF I <=4 THEN
                                        DO;
                                                DO J= I TO 1 BY -1;
                                                    TIME=CATS("T1_M",I,"_",YEAR(INTNX("MONTH",X,-1)));
                                                    YRMO=INPUT(PUT(INTNX("MONTH",X,-MONTH(INTNX("MONTH",X,-1))+J-1),YYMMN6.),6.);
                                                     OUTPUT;
                                                END;
                                       END;
                              ELSE DO;
                                             DO J= I TO 5 BY -1;
                                                  TIME=CATS("T2_M",I-4,"_",YEAR(INTNX("MONTH",X,-1)));
                                                  YRMO=INPUT(PUT(INTNX("MONTH",X,-MONTH(INTNX("MONTH",X,-1))+J-1),YYMMN6.),6.);
                                                  OUTPUT;
                                            END;
                                       END;
                     END;
END;
/*******FOR SEP TO DEC MONTH*********/

IF 8< MONTH(INTNX("MONTH",X,-1))<=12 THEN
                   DO ;
                          DO I= MONTH(INTNX("MONTH",X,-1)) TO 1 BY -1;
                               IF I <=4 THEN
                                       DO;
                                             DO J= I TO 1 BY -1;
                                                   TIME=CATS("T1_M",I,"_",YEAR(INTNX("MONTH",X,-1)));
                                                   YRMO=INPUT(PUT(INTNX("MONTH",X,-MONTH(INTNX("MONTH",X,-1))+J-1),YYMMN6.),6.);
                                                  OUTPUT;
                                            END;
                                      END;
                              ELSE IF 4< I <=8 THEN
                                       DO;
                                           DO J= I TO 5 BY -1;
                                              TIME=CATS("T2_M",I-4,"_",YEAR(INTNX("MONTH",X,-1)));
                                              YRMO=INPUT(PUT(INTNX("MONTH",X,-MONTH(INTNX("MONTH",X,-1))+J-1),YYMMN6.),6.);
                                              OUTPUT;
                                           END;
                                       END;
                           ELSE IF 8< I <=12 THEN
                                      DO;
                                          DO J= I TO 9 BY -1;
                                             TIME=CATS("T3_M",I-8,"_",YEAR(INTNX("MONTH",X,-1)));
                                            YRMO=INPUT(PUT(INTNX("MONTH",X,-MONTH(INTNX("MONTH",X,-1))+J-1),YYMMN6.),6.);
                                            OUTPUT;
                                         END;
                                      END;
              END;
END;


RUN;

 

Super Contributor
Posts: 345

Re: Creating Trimester using data step

Still hardly possible to understand why you are doing what you are doing.

Super Contributor
Posts: 266

Re: Creating Trimester using data step

Posted in reply to andreas_lds

Hi, I using to generate few reports . my question is simple that can i get this output more simply methor/code?

Super User
Posts: 7,766

Re: Creating Trimester using data step

So I guess you might want this:

%let year=15;

data want1;
do month = 1 to 12;
  month_print = put(mdy(month,1,&year),monyy5.);
  t = int((month-1)/4) + 1;
  do m = mod(month-1,4)+1 to 4;
    period = 'T'!!put(t,1.)!!'M'!!put(m,1.);
    output;
  end;
end;
run;

proc sort
  data=want1
  out=want(keep=month_print period)
;
by period month;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super Contributor
Posts: 266

Re: Creating Trimester using data step

Posted in reply to KurtBremser

Hi, 

 

Thanks a lot for your valuable time and solution over my problem.

I need it dyanamic as i mention that when i will run it on December then it will give me output till november on same patter as ur code is providing output. i.e in Jan it will give complete last year output , in Feb it will give only Jan T1M1 and Mar it will give :

Jan T1M1

Jan T2m2

Feb T2M2

as so on.

 

Thanks

Super User
Posts: 7,766

Re: Creating Trimester using data step

Within each month, you already have the code that gives the entries for that particular month, as you stated in your OP.

If you need the window to roll over years, you need an addtional outer loop over the years and within the years start and end with the correct required months.

If it is more complicated than that, you need to specify the wanted output for different time windows.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super Contributor
Posts: 266

Re: Creating Trimester using data step

Posted in reply to KurtBremser

As i have mentioned in my previous post:

i have only value is today();

in case if i will run the code in month of jan -16 then i will get out put :

JAN15 T1M1

JAN15 T1M2

FEB15 T1M2

JAN15 T1M3

FEB15 T1M3

MAR15 T1M3

JAN15 T1M4

FEB15 T1M4

MAR15 T1M4

APR15  T1M4

MAY15 T2M1

MAY15 T2M2

 

JUN15  T2M2

MAY15 T2M3

JUN15  T2M3

 

JUL15   T2M3

MAY15 T2M4

JUN15  T2M4 

JUL15   T2M4

 

AUG15  T2M4

SEP15 T3M1

SEP15  T3M2

OCT15 T3M2

SEP15  T3M3

OCT15 T3M3

 

NOV15 T3M3

SEP15  T3M4

OCT15 T3M4

NOV15 T3M4

DEC15 T3M4

 

WHEN I WILL RUN IN FEB16 THEN I WILL GET OUTPUT :

JAN16 T1M1

WHEN I WILL RUN IN MAR16 THEN I WILL GET OUTPUT :

JAN16 T1M1

JAN16 T1M2

FEB16 T1M2

WHEN I WILL RUN IN APR16 THEN I WILL GET OUTPUT :

JAN16 T1M1

JAN16 T1M2

FEB16 T1M2

 

JAN16 T1M3

FEB16 T1M3

MAR16 T1M3

WHEN I WILL RUN IN MAY16 THEN I WILL GET OUTPUT :

JAN16 T1M1

JAN16 T1M2

FEB16 T1M2

JAN16 T1M3

FEB16 T1M3

MAR16 T1M3

JAN16 T1M4

FEB16 T1M4

MAR16 T1M4

APR16 T1M4

WHEN I WILL RUN IN JUN16 THEN I WILL GET OUTPUT :

MAY16 T2M1

WHEN I WILL RUN IN JUL16 THEN I WILL GET OUTPUT :

MAY16 T2M1

MAY16 T2M2

JUN16 T2M2

WHEN I WILL RUN IN AUG16 THEN I WILL GET OUTPUT :

MAY16 T2M1

MAY16 T2M2

JUN16 T2M2

MAY16 T2M3

JUN16 T2M3

JUL16 T2M3

WHEN I WILL RUN IN SEP16 THEN I WILL GET OUTPUT :

MAY16 T2M1

MAY16 T2M2

JUN16 T2M2

MAY16 T2M3

JUN16 T2M3

JUL16 T2M3

MAY16 T2M4

JUN16 T2M4

JUL16 T2M4

AUG16 T2M4

WHEN I WILL RUN IN OCT16 THEN I WILL GET OUTPUT :

SEP16 T3M1

WHEN I WILL RUN IN NOV16 THEN I WILL GET OUTPUT :

SEP16 T3M1

SEP16 T3M2

OCT16 T3M2

WHEN I WILL RUN IN DEC16 THEN I WILL GET OUTPUT :

SEP16 T3M1

SEP16 T3M2

OCT16 T3M2

SEP16 T3M3

OCT16 T3M3

NOV16 T3M3

WHEN I WILL RUN IN JAN1716 THEN I WILL GET OUTPUT :

SEP16 T3M1

SEP16 T3M2

OCT16 T3M2

SEP16 T3M3

OCT16 T3M3

NOV16 T3M3

SEP16 T3M4

OCT16 T3M4

NOV16 T3M4

DEC16 T3M4

 

 

THIS IS A SAMPLE FOR MY DESIRE OUTPUT: HERE MMDDYYN10. COLUMN ALSO ADDED FOR RESPECTIVE FIRST DAY OF MONTH I.E FOR JAN15 - 01012015

 

I HOPE IT WILL HELP YOU TO UNDERSTAND MY REQUEST

 

 

 

 

Solution
‎02-22-2016 05:07 AM
Super User
Posts: 7,766

Re: Creating Trimester using data step

data _null_;
date = date();
date = intnx('month',date,-1);
call symput('year',substr(put(year(date),z4.),3,2));
startmonth = int((month(date)-1)/4) * 4 +1;
call symput('startmonth',strip(put(startmonth,2.)));
call symput('endmonth',strip(put(month(date),2.)));
run;

data want1;
do month = &startmonth to &endmonth;
  month_print = put(mdy(month,1,&year),monyy5.);
  t = int((month-1)/4) + 1;
  if &startmonth = 1 and &endmonth = 12 /* whole year */
  then stopmonth = 4;
  else stopmonth = min(4,&endmonth-(t-1)*4);
  do m = mod(month-1,4)+1 to stopmonth;
    period = 'T'!!put(t,1.)!!'M'!!put(m,1.);
    output;
  end;
end;
run;

proc sort
  data=want1
  out=want(keep=month_print period)
;
by period month;
run;

To get the whole year, add

%let startmonth=1;

before the data want1 step

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super Contributor
Posts: 266

Re: Creating Trimester using data step

Posted in reply to KurtBremser

Thanks, in my code x is a trigger as date() or today(). 

we can replace x by date() or today(). i  use check the data/movement for whole year.

in ur code its breaking for 4-4 month, its my mistake i have provided you output like that. 

 

Thanks a lot.

☑ This topic is solved.

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

Discussion stats
  • 10 replies
  • 410 views
  • 0 likes
  • 3 in conversation