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

Hi Team,

I don't have sas/ets and was trying to see if this question has been raised and answered previously.

 

I am trying to create a rolling 12 month total which calculates the sum of the last 12 months.

 

MonthAsum(rolling 12 months)
April 20181.
May 201823
June 201836
July 2018410
August 2018515
September 2018621
October 2018728
November 2018836
December 2018945
January 20191055
February 20191166
March 20191278
April 20191390
May 201914102
June 201915114
July 201916126
August 201917138
September 201918150
October 201919162
November 201920174
1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

Or Use lag

 

data have;
input Month :monyy7.	A ;
format month monyy7.;
cards;
Apr-18	1
May-18	2
Jun-18	3
Jul-18	4
Aug-18	5
Sep-18	6
Oct-18	7
Nov-18	8
Dec-18	9
Jan-19	10
Feb-19	11
Mar-19	12
Apr-19	13
May-19	14
Jun-19	15
Jul-19	16
Aug-19	17
Sep-19	18
Oct-19	19
Nov-19	20
;
data want;
set have;
s+a;
k=lag12(s);
want=s-sum(k,0);
drop k s;
run;

View solution in original post

17 REPLIES 17
novinosrin
Tourmaline | Level 20

12 month windows super simple , however do you have an ID variable or is it just that one set? i.e no groups?

Ramakanthkrovi
Obsidian | Level 7

No ID variable. for every month I just need the actual (a) and sum(a to a-11).

novinosrin
Tourmaline | Level 20

Hi @Ramakanthkrovi   Thank you. The logic is very simple.

 

The window condition 

on intnx('mon',a.month,-11)<=b.month<=a.month

according to your needs below


data have;
input Month :monyy7.	A ;
format month monyy7.;
cards;
Apr-18	1
May-18	2
Jun-18	3
Jul-18	4
Aug-18	5
Sep-18	6
Oct-18	7
Nov-18	8
Dec-18	9
Jan-19	10
Feb-19	11
Mar-19	12
Apr-19	13
May-19	14
Jun-19	15
Jul-19	16
Aug-19	17
Sep-19	18
Oct-19	19
Nov-19	20
;

proc sql;
create table want as
select a.* ,sum(b.a) as sum 
from have a left join have b
on intnx('mon',a.month,-11)<=b.month<=a.month
group by a.month ,a.a
order by a.month;
quit;

 

novinosrin
Tourmaline | Level 20

Or Use lag

 

data have;
input Month :monyy7.	A ;
format month monyy7.;
cards;
Apr-18	1
May-18	2
Jun-18	3
Jul-18	4
Aug-18	5
Sep-18	6
Oct-18	7
Nov-18	8
Dec-18	9
Jan-19	10
Feb-19	11
Mar-19	12
Apr-19	13
May-19	14
Jun-19	15
Jul-19	16
Aug-19	17
Sep-19	18
Oct-19	19
Nov-19	20
;
data want;
set have;
s+a;
k=lag12(s);
want=s-sum(k,0);
drop k s;
run;
PaigeMiller
Diamond | Level 26

If you have PROC EXPAND in your SAS license, use that, it's a lot easier than having to write a program to do it yourself.

--
Paige Miller
Ramakanthkrovi
Obsidian | Level 7

Hi @PaigeMiller - 

no, unfortunately we don't have sas/ets licence.

 

I was also looking to do this in SAS VA (7.4) if possible. is it simpler than writing a program?

 

Reeza
Super User

VA has built in functionality to handle date dimensions - is your variable formatted and identified as a date in VA?

 

https://communities.sas.com/t5/SAS-Communities-Library/3-FAQs-on-date-calculations-in-SAS-Visual-Ana...

 

 

Ramakanthkrovi
Obsidian | Level 7

 

I had to do this to get a rolling 12 month figure. the article is not informative for what I was trying to do. otherwise it works.

 

RelativePeriod(_Sum_, 'NDC'n, _ApplyAllFilters_, 'Reg_Mon'n, _ByMonth_, 0, _Full_, {Date}) + RelativePeriod(_Sum_, 'NDC'n, _ApplyAllFilters_, 'Reg_Mon'n, _ByMonth_, -1, _Full_, {Date}) + RelativePeriod(_Sum_, 'NDC'n, _ApplyAllFilters_, 'Reg_Mon'n, _ByMonth_, -2, _Full_, {Date}) + RelativePeriod(_Sum_, 'NDC'n, _ApplyAllFilters_, 'Reg_Mon'n, _ByMonth_, -3, _Full_, {Date})

 

+ ...

 

+RelativePeriod(_Sum_, 'NDC'n, _ApplyAllFilters_, 'Reg_Mon'n, _ByMonth_, -11, _Full_, {Date}) + RelativePeriod(_Sum_, 'NDC'n, _ApplyAllFilters_, 'Reg_Mon'n, _ByMonth_, -12, _Full_, {Date})

Ramakanthkrovi
Obsidian | Level 7

Thank you @novinosrin - The lag worked great.

 

Is it simpler to do this way if we have multiple columns or is there a way I can do it in SAS VA 7.4?

novinosrin
Tourmaline | Level 20

I have no idea about SAS VA and have never used it. The LAG usage here is mere simple arithmetic. I suggest using that. The number of columns is immaterial as your monthyear variable is continuous. Programming using continuous variable is generally easy

novinosrin
Tourmaline | Level 20

Hello @Ramakanthkrovi  Some extra fun with temp array

 



data have;
input Month :monyy7.	A ;
format month monyy7.;
cards;
Apr-18	1
May-18	2
Jun-18	3
Jul-18	4
Aug-18	5
Sep-18	6
Oct-18	7
Nov-18	8
Dec-18	9
Jan-19	10
Feb-19	11
Mar-19	12
Apr-19	13
May-19	14
Jun-19	15
Jul-19	16
Aug-19	17
Sep-19	18
Oct-19	19
Nov-19	20
;

data want;
 do _n_=1 by 1 until(z); 
  set have end=z;
  array t(0:11) _temporary_;
  t(mod(_n_,12))=a;
  s=sum(of t(*));
  output;
 end;
run;

 

 

novinosrin
Tourmaline | Level 20

data have;
input Month :monyy7.	A ;
format month monyy7.;
cards;
Apr-18	1
May-18	2
Jun-18	3
Jul-18	4
Aug-18	5
Sep-18	6
Oct-18	7
Nov-18	8
Dec-18	9
Jan-19	10
Feb-19	11
Mar-19	12
Apr-19	13
May-19	14
Jun-19	15
Jul-19	16
Aug-19	17
Sep-19	18
Oct-19	19
Nov-19	20
;
data want;
if _n_=1 then do;
  if 0 then set have(rename=(month=_m a=_a));
   dcl hash H (dataset:'have(rename=(month=_m a=_a))') ;
   h.definekey  ("_m") ;
   h.definedata ("_m","_a") ;
   h.definedone () ;
   dcl hiter hi('h');
 end;
 set have;
 do while(hi.next()=0);
  if intnx('mon',month,-11)<=_m<=month then sum=sum(sum,_a);
 end;
 drop _:;
 run;
Ramakanthkrovi
Obsidian | Level 7

Thank you @novinosrin - if there is an ID variable, what will be the impact on the code?

 

RegionMonthAsum(rolling 12 months)
AustraliaApril 20181.
AustraliaMay 201823
AustraliaJune 201836
AustraliaJuly 2018410
AustraliaAugust 2018515
AustraliaSeptember 2018621
AustraliaOctober 2018728
AustraliaNovember 2018836
AustraliaDecember 2018945
AustraliaJanuary 20191055
AustraliaFebruary 20191166
AustraliaMarch 20191278
AustraliaApril 20191390
AustraliaMay 201914102
NZApril 20181.
NZMay 201823
NZJune 201836
NZJuly 2018410
NZAugust 2018515
NZSeptember 2018621
NZOctober 2018728
NZNovember 2018836
NZDecember 2018945
NZJanuary 20191055
NZFebruary 20191166
NZMarch 20191278
NZApril 20191390
NZMay 201914102

 

 

novinosrin
Tourmaline | Level 20

Hello @Ramakanthkrovi  Now you are talking. I asked earlier the same and you categorically said NO. 🙂

 

Anyways, let us know which solution in (SQL,LAG,ARRAY,HASH) you want to use and we shall work with that alone. Plus, I got the initial impression that you didn't really seem to go for a programming solution and rather a VA solution. So please think over and ask your teammates(senior)/boss at work as to what should be done and how it should be done. 

 

Finally, while the slight modification is rather too simple however would you/your team be able to maintain,modify and update programming solutions considering you may be completely from a different background as a whole. Believe it or not, at my place of work any of the advance techniques are NOT welcome coz many even prefer 1000 lines of hard coding and some seniors deem that as "different" coding style while I call it "substandard". lol 🙂

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 17 replies
  • 5382 views
  • 4 likes
  • 6 in conversation