1

I tried to subtract decimal years from date in order to get initial date, something like this question but I am using years with a decimal part, ej: 5.5 years, I need the origin date from that difference, like this:

library(lubridate)
ymd("2021-05-21")-years(5.5)
# 2015-11-21 desired output

But, this give an error because years function only accepts integers. How can I achieve this?

Israel
  • 260
  • 3
  • 15

2 Answers2

1

We could use years and months

v1 <- 5.5
yr <- as.integer(v1)
mth <- as.integer((v1* 12) %% 12)
ymd("2021-05-21") - (years(yr) + months(mth))
#[1] "2015-11-21"
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Edit improve last answer! awesome! – Israel May 20 '21 at 17:39
  • 1
    @Israel i know, the only issue I see is the decimal to convert to months i..e after extracting the 5, probably, it is `12 * 5/12` or so – akrun May 20 '21 at 17:45
  • yeah, you are right! I will edit question in order to explain better – Israel May 20 '21 at 17:48
  • I eddited @akrun . Could you edit your answer by applying what was entered in your comment? – Israel May 20 '21 at 17:54
  • 1
    Please revert your answer to ``` ymd("2021-05-21") - (years(as.integer(v1)) + months((v1* 12) %% 12))``` @akrun because I edited, decimal part of 5.5 refers to 0.5 years, you are right in your comments – Israel May 20 '21 at 18:04
  • Or just change the output of your last answer to "2015-11-21", and it is correct and more specific – Israel May 20 '21 at 18:22
  • 1
    @Israel sorry, I was checking your output earlier, and I thought mine is incorrect – akrun May 20 '21 at 18:24
0

It is tricky to calculate time differences accurately, especially perhaps years. Sources such as Wikipedia talk about an average length of a Gregorian year of g = 365.2425 days, taking account for leap years (not yet for leap seconds, though, which are not regular). Anyway, we could assume g as the average length of a year, neglecting the actual number of leap days in our time difference and define a function add_yr() that should be reasonably valid for dates after October 15, 1582.

add_yr <- \(d, y) as.Date(d) + y * 365.2425

(prior to R4.1.* use this code: add_yr <- function(d, y) as.Date(d) + y * 365.2425)

This shows that we need to insert -5.495 instead of -5.5 to get OP's desired date ("2015-11-21").

add_yr("2021-05-21", -5.495)
# [1] "2015-11-21"

add_yr("2021-05-21", -5.5)
# [1] "2015-11-20"

The gain in accuracy is almost 2 days in this case:

(5.5 - 5.495) * 365.2425
# [1] 1.826212
jay.sf
  • 60,139
  • 8
  • 53
  • 110