-1

I am using R studio and want to create a new column called period, such that if the month of assessment is May2015 then this is coded as 0 and anything below that is coded as -1, -2, -3, and so on and anything after that is coded as 1, 2, 3, 4, and so on. I have uploaded my example data and code to see what I have done. Your assistance will be greatly appreciated. Thank you, Baz.

Baz
  • 49
  • 3
  • 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 Answers2

2

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
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
0

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) )
Ray
  • 2,008
  • 14
  • 21