BookmarkSubscribeRSS Feed
djk200399
Fluorite | Level 6

Hi, I am progressing through my code and have an annoyingly long calculation that is very repetitive, however, one element of it uses a calculation as a one off. I want to be able to simplify this so I am not writing it multiple times. I have included my test attempt code at the bottom to show what I was trying to do (but failing miserably)

 

data calc;
set withdrawal_data;
do wdwl_FC_1=((Bal_Oct20+(Bal_Oct20*Money_Out_1))+(Adjustments_1*1000000)); end;
do wdwl_FC_2 = ((wdwl_FC_1+(wdwl_FC_1*Money_Out_1))+(Adjustments_1*1000000));

wdwl_FC_3 = ((wdwl_FC_2+(wdwl_FC_2*Money_Out_2))+(Adjustments_2*1000000));

wdwl_FC_4 = ((wdwl_FC_3+(wdwl_FC_3*Money_Out_3))+(Adjustments_3*1000000));

wdwl_FC_5 = ((wdwl_FC_4+(wdwl_FC_4*Money_Out_4))+(Adjustments_4*1000000));

wdwl_FC_6 = ((wdwl_FC_5+(wdwl_FC_5*Money_Out_5))+(Adjustments_5*1000000));

wdwl_FC_7 = ((wdwl_FC_6+(wdwl_FC_6*Money_Out_6))+(Adjustments_6*1000000));

wdwl_FC_8 = ((wdwl_FC_7+(wdwl_FC_7*Money_Out_7))+(Adjustments_7*1000000));

wdwl_FC_9 = ((wdwl_FC_8+(wdwl_FC_8*Money_Out_8))+(Adjustments_8*1000000));

wdwl_FC_10 = ((wdwl_FC_9+(wdwl_FC_9*Money_Out_9))+(Adjustments_9*1000000));

wdwl_FC_11 = ((wdwl_FC_10+(wdwl_FC_10*Money_Out_10))+(Adjustments_10*1000000));

wdwl_FC_12 = ((wdwl_FC_11+(wdwl_FC_11*Money_Out_11))+(Adjustments_11*1000000));
end;

run;
*Note this goes on for 60 iterations so I have only included 12 here and in my test

I have done the first (different) calc separately in another dataset in my test to try and get round the issue with the following code but

get errors in the arrays bit. Please can you help resolve this for me as driving me mad again. If there is a better way to do this instead of the arrays please let me know.

 

 

data calc;
set wdwl_calc;
wdwl_FC_202010=((Bal_Oct20+(Bal_Oct20*Money_Out_202010))+(Adjustments_202010*1000000));
run;

 

data fcast;
set calc;
run;


data tester;
set fcast;

array money (202010:202109) Money_Out_202010 - Money_Out_202109;
array wdwl (202010:202109) Adjustments_202010 - Adjustments_202109;
array fcwdrawal(12);
array wdrwal (202010:202109) Withdrawal_FC_202010 - Withdrawal_FC_202109;
do i = 1 to 12;
fcwdrawal(i) = ((Withdrawal_FC_202010+(fcwdrawal(i)*money(i)))+(wdwl(i)*1000000));
end;
run;

 

Thank you

 

David

 

13 REPLIES 13
Kurt_Bremser
Super User

From your code, I take it that you suffer from a bad dataset layout (data (dates) in structure (column names)).

You should first transpose that to a long layout, and then you do a running calculation with retained variables.

For help with the transposition, supply a short example of your dataset, ideally as a data step with datalines.

Astounding
PROC Star
Your array dimensions are off.

(202010:202109)

This includes all integers in the range, such as 202013, 202014, all the way through 202099.
djk200399
Fluorite | Level 6

So as the data has each element with a date and month in it ie 202010 for October 20 what would I need to change the dimensions to in order to get it to pull these through.

 

PaigeMiller
Diamond | Level 26

@djk200399 wrote:

So as the data has each element with a date and month in it ie 202010 for October 20 what would I need to change the dimensions to in order to get it to pull these through.

 


Show us a portion of the data, following these instructions: https://blogs.sas.com/content/sastraining/2016/03/11/jedi-sas-tricks-data-to-data-step-macro/

--
Paige Miller
Tom
Super User Tom
Super User

Fix the index into the array.

data tester;
  set fcast;
  array money Money_Out_202010 - Money_Out_202012 Money_Out_202101-Money_Out_202109;
  array wdwl Adjustments_202010 - Adjustments_202012 Adjustments_202101 - Adjustments_202109;
  array fcwdrawal [12];
  array wdrwal  Withdrawal_FC_202010 - Withdrawal_FC_202012 Withdrawal_FC_202101 - Withdrawal_FC_202109;
  do i = 1 to 12;
    fcwdrawal[i] = ((Withdrawal_FC_202010+(fcwdrawal[i]*money[i]))+(wdwl[i]*1000000));
  end;
run;
djk200399
Fluorite | Level 6

Hi Tom, 

So are you suggesting if I have an array with the multiple years noted next to it, as you have done here it should fix the issue?


I will give this a go on the code later on. Thank you

djk200399
Fluorite | Level 6

Hi Tom, 

 

I tried your suggestion but get an error saying array subscript out of range at line 30 column 20. I will try and sort the sharing of a dataset on Monday that way it might be easier to see what I am doing wrong !

 

djk200399
Fluorite | Level 6

I have transposed my datasets (which I know do all the time when reading them in from excel) to improve things but need to work out how to do this via an array.

 

I have 2 data sets that look like this

Dataset A    
nobrandproductperiodacc
1ARegular202010300
2AFixed202010350
3BRegular202010250
4BFixed202010200
5CRegular202010150
1ARegular202011250
2AFixed202011250
3BRegular202011400
4BFixed202011200
5CRegular202011150
1ARegular202012150
2AFixed202012160
3BRegular202012300
4BFixed202012200
5CRegular202012400
1ARegular202101450
2AFixed202101325
3BRegular202101350
4BFixed202101275
5CRegular202101

190

 

 

 

Dataset B    
nobrandproductperiodint
1ARegular20201110
2AFixed20201112
3BRegular20201112
4BFixed20201110
5CRegular20201115
1ARegular20201220
2AFixed20201213
3BRegular20201212
4BFixed2020125
5CRegular2020127
1ARegular2021012
2AFixed20210111
3BRegular2021013
4BFixed2021013
5CRegular20210114
1ARegular20210212
2AFixed20210212
3BRegular20210212
4BFixed20210210
5CRegular20210210

 

I want to use the 2 datasets to undertake an ongoing calculation

The first dataset is one that was created last month with forecast numbers going forward from an actual position in 202010

The second is the new calculation that needs to take place on this dataset but using the prior month result

So in the case of no1 the first calc should be acc for 202010 from dataset A plus int for 202011 from dataset B. The second calc should use the outcome of the first calc as it's starting point and then add int for 202012 from dataset B and so on until the end.

How do I use the result of each calc for the next calculation simply and efficiently ?

 

What I should see here results wise using no1 as an example is 

 

 calc
202011310
202012330
202101332
202102344

 

I hope this makes sense and would an array work to do this or am I over complicating things??

 

Thanks in advance of your help again

PaigeMiller
Diamond | Level 26

Repeating my earlier request to you in this thread

 

Show us a portion of the data, following these instructions: https://blogs.sas.com/content/sastraining/2016/03/11/jedi-sas-tricks-data-to-data-step-macro/

--
Paige Miller
djk200399
Fluorite | Level 6

I have tried running the said macro but it does not work in my SAS given some of the internal restrictions. Instead I have attached the two datasets (simplified versions) as csv's for a quick upload. 

 

So for these I need a calculation of acc from accrual dataset at 202010 + the value of calc from the all1 dataset for 202011 merged by the no1 field and then the next calculation will be the last calculation we did + value of calc from the all dataset for 202012 merged by the no1 field and so on.

 

Appreciate your help on this.

Kurt_Bremser
Super User
proc sort
  data=ds_a (where=(period='01oct2020'd))
  out=ds_a_
;
by brand product;
run;

proc sort
  data=ds_b (where=(period ge '01nov2020'd))
  out=ds_b_
;
by brand product_period;
run;

data want;
merge
  ds_a_
  ds_b_
;
by brand product;
if first.product
then calc = acc;
calc + int;
keep brand product calc;
run;

Untested, for lack of usable data.

djk200399
Fluorite | Level 6

Apologies for not including the correct data, I managed to do a similar solution to yours Kurt so apologies for the failure on my part

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 13 replies
  • 2003 views
  • 0 likes
  • 5 in conversation