Show what you currently have.
Then show, using that example, what you expect as a result. Your current example doesn't show anyplace to get 15 for the first line.
Caution: Previous month when there is no YEAR value is very problematic. If you only have "JAN" and "DEC" in your data how do you know which "DEC" come before "JAN"??
IF your data is all one year then there is no "previous month" for Jan.
Months as 3-letter abbreviations are not easy to work with in general, even worse they aren't even all the same length. They do not sort. You have to explicitly describe rules for what is prior, or following, AND you need an extra rule for every interval, 2 months prior or 2 months after that may be needed.
Suggestion is create an actual DATE because SAS provides tools to examine dates, increment and display.
First is provide example data in the form or a working data step. I suspect this has been mentioned before. Something like:
data have; input Cust_id Month $ Txn_count; datalines; 1 Jan 15 1 Feb 5 1 May 12 1 June 4 2 Sept 64 2 Dec 6 3 Aug 34 3 Sept 2 3 Oct 23 ;
With that then we have one possible solution (there are others)
data want; set have; by cust_id notsorted; datevar = input(cats('01',substr(month,1,3),'2023'),date9.); format datevar monname3.; month_previous = intnx('month',datevar,-1,'b'); format month_previous monname3.; txn_count_previous = lag(txn_count); if first.cust_id then txn_count_previous = 0; run;
We create a SAS date value by creating a string that is in the form of ddMONyyyy, or 01JAN2023 and read that with an informat designed to do such. Note: SEPT is right out (why? only month with 4 characters).
The format statement makes the default appearance 3 letters such as Jan. With that value in hand we can use the SAS INTNX function to increment the value, in this case by month, -1 is "previous", and 'b' says beginning of the month.
Noticing that you changed the description of the problem again by introducing custid as variable to consider as a group, meaning the count assignment I add the BY Cust_Id. When you process data in a data step SAS provides automatic variables to indicate whether a particular observation is from the first or last record of a group. The variables accessed using First.variablename or Last.variablename and have values of 1 (for Yes, is first or is last) or 0. So we can conditionally do things at the start or the end of the group. The NOTSORTED means treat the values as group but may not be actual sort order as the BY statement expects without the option.
The LAG function gets the value from the previous record. Conditionally we assign the desired value of 0 when the first of the cust_id values is reached.
I left the new Datevar in the data in case you need to do anything that uses "month" in actual month order.
If
data want;
set have;
by cust_id;
array mon_list {2,12} $3
_temporary_ ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',
'Dec','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov');
cur_month=propcase(substr(month,1,3));
prv_month=mon_list{2,whichc(cur_month,of mon_list{*})};
txn_count_previous = ifn(lag(cur_month)=prv_month and first.cust_id=0,lag(txn_count),0);
run;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.