Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write this -working- code to improve performance?

I have this sample set out of a bigger dataset (25K records). I noticed that the code of my app slows down on this piece and I want to check for performance improvement.

context : my financial years starts July and ends in June. Therefore my records have a Financial Period and Financial Year that is different than a month and a calendar Year. I want to add extra columns indicating the calendar year and month.

FinancialPeriod-FinancialYear : 01 2018 is 7 2017 (Jul 2017),
FinancialPeriod-FinancialYear : 07 2018 is 1 2018 (Jan 2018), etc..

Reproducible example :

dt<-data.table(FinancialPeriod =c(3,4,4,5,1,2,8,8,11,12,2,3,10,1,6), FinancialYear=c(2018), Amount=c(12,14,16,18,12))
dt$Month<-dt$FinancialPeriod + 6
dt$Year<-dt$FinancialYear
t1<-proc.time()
for(row in 1:nrow(dt)){
  if (dt[row,"Month"] > 12){
    dt[row,"Month"]<- dt[row,"Month"] -12
  } 
  else {
    dt[row,"Year"]<- dt[row,"Year"] -1
  }
}
proc.time()-t1
dt

The code above works, but works slow. I would like to have suggestions on how to improve.

like image 442
Philippe Avatar asked Sep 21 '26 07:09

Philippe


1 Answers

My suggestion is to use a full date, e.g., the begin of a financial period. So, we can use a FinancialDate instead of a FinancialPeriod-FinancialYear combo, e.g., OP's example

FinancialPeriod-FinancialYear : 01 2018

becomes

FinancialDate: 2018-01-01

This approach has several benefits:

  1. There is only one date object describing the period instead of two objects which is easier to handle, e.g., for aggregations. If required, month and year are easily extracted from a date object.
  2. We can take advantage of the usual date arithmetic, e.g., of the lubridate package, to convert a FinancialDate into a CalendarDate.
  3. Also, plotting works better for date objects.

Here is the code:

library(lubridate)
dt[, FinDate := make_date(FinancialYear, FinancialPeriod)]
dt[, CalDate := FinDate %m+% months(6)]   # convert to calendar date by adding offset
dt[, c("CalMonth", "CalYear") := list(month(CalDate), year(CalDate))]
dt
    FinancialPeriod FinancialYear Amount Month Year    FinDate    CalDate CalMonth CalYear
 1:               3          2018     12     9 2018 2018-03-01 2018-09-01        9    2018
 2:               4          2018     14    10 2018 2018-04-01 2018-10-01       10    2018
 3:               4          2018     16    10 2018 2018-04-01 2018-10-01       10    2018
 4:               5          2018     18    11 2018 2018-05-01 2018-11-01       11    2018
 5:               1          2018     12     7 2018 2018-01-01 2018-07-01        7    2018
 6:               2          2018     12     8 2018 2018-02-01 2018-08-01        8    2018
 7:               8          2018     14    14 2018 2018-08-01 2019-02-01        2    2019
 8:               8          2018     16    14 2018 2018-08-01 2019-02-01        2    2019
 9:              11          2018     18    17 2018 2018-11-01 2019-05-01        5    2019
10:              12          2018     12    18 2018 2018-12-01 2019-06-01        6    2019
11:               2          2018     12     8 2018 2018-02-01 2018-08-01        8    2018
12:               3          2018     14     9 2018 2018-03-01 2018-09-01        9    2018
13:              10          2018     16    16 2018 2018-10-01 2019-04-01        4    2019
14:               1          2018     18     7 2018 2018-01-01 2018-07-01        7    2018
15:               6          2018     12    12 2018 2018-06-01 2018-12-01       12    2018
like image 148
Uwe Avatar answered Sep 23 '26 22:09

Uwe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!