-
Two things, 1) I appreciate you showing your work, but it is often good to leave some code in the Stack overflow post so its easier for us to copy and paste your work. see [reprex guide](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). 2) I think you will benefit from the `lubridate` package if you are trying to do a non-equal comparison between two dates. – Justin Landis May 06 '21 at 18:24
-
The input data shown in reproducible form and any code you have should be in the question. I have placed the `dput` output of the original data, before it was deleted from the question, in the Note at the end of my answer. – G. Grothendieck May 06 '21 at 18:35
-
Also read the info at the top of the [tag:r] tag about NOT using images since then no one can easily copy your code and data without tediously retyping it. – G. Grothendieck May 06 '21 at 18:59
2 Answers
See Note at end for input data. It was originally in question but seems to have disappeared.
1) yearmon Convert the date to yearmon class. Internally it represents dates as the year +0 for Jan, +1/12 for Feb, ..., +11/12 for Dec so subtracting the yearmon of May2015 and multiplying the difference by 12 gives the number of months. We also use sub
to take only the first 3 letters of the month as that is the form of abbreviation that R recognizes.
library(zoo)
transform(data, period =
12 * (as.yearmon(sub("^(...).*(....)$", "\\1\\2", testDate), "%b%Y") -
as.yearmon("2015-05")))
giving:
testDate period
1 April2014 -13
2 May2014 -12
3 June2014 -11
4 July2014 -10
5 Aug2014 -9
6 Sept2014 -8
7 Oct2014 -7
8 Nov2014 -6
9 Dec2014 -5
10 Jan2015 -4
11 Feb2015 -3
12 March2015 -2
13 April2015 -1
14 May2015 0
15 June2015 1
16 July2015 2
17 Aug2015 3
18 Sept2015 4
19 Oct2015 5
20 Nov2015 6
21 Dec2015 7
2) Base R If we knew that the dates are consecutive months then we could just subtract row numbers and no packages are needed:
transform(data, period = 1:nrow(data) - match("May2015", testDate))
Note
data <- structure(list(testDate = c("April2014", "May2014", "June2014",
"July2014", "Aug2014", "Sept2014", "Oct2014", "Nov2014", "Dec2014",
"Jan2015", "Feb2015", "March2015", "April2015", "May2015", "June2015",
"July2015", "Aug2015", "Sept2015", "Oct2015", "Nov2015", "Dec2015"
)), class = "data.frame", row.names = c(NA, -21L))
It looks like this:
> data
testDate
1 April2014
2 May2014
3 June2014
4 July2014
5 Aug2014
6 Sept2014
7 Oct2014
8 Nov2014
9 Dec2014
10 Jan2015
11 Feb2015
12 March2015
13 April2015
14 May2015
15 June2015
16 July2015
17 Aug2015
18 Sept2015
19 Oct2015
20 Nov2015
21 Dec2015

- 254,981
- 17
- 203
- 341
If you want to use a tidyverse package, {lubridate}
offers quite some support for date-time handling.
Working with dates, I define the first of months as the date. If you need to work with year-month notation, you can overwrite this when you have your result that you want.
I define a sequence of dates as you did not provide a reproducible example. Hope this helps/get you going. Good luck.
library(lubridate)
# define dataframe with sequence of test-dates
data <- data.frame(testDate = seq(from = ymd("2014-04-01")
, to = lubridate::ymd("2015-12-01")
, by = "1 month"))
data %>%
# in lubridate you can define a time interval and the convert this into a period
# lubridate does not support units = "months", thus we "divide" our period into months
# with "%/%" and 1 month -> months(1)
mutate( period = interval(ymd("2015-05-01"), testDate) %>% as.period() %/% months(1)
,period2 = interval(testDate, ymd("2015-05-01")) %>% as.period() %/% months(1) )

- 2,008
- 14
- 21