-1

I have data in R that has a numeric variable that counts the number of months since Jan. 1960.

Let’s say:

months_since_1960 <- c(0, 1, 12, 13, 24, 25)

How can I create a new date variable that will show me these dates in a valuable way? I'm hoping for something like:

date <- (1960-01,1960-02,1961-01,1961-02,1962-01,1962-02)

I'm sure it's an easy fix but I've tried identifying this and I can't seem to figure it out...

Nick Cox
  • 35,529
  • 6
  • 31
  • 47
user21027866
  • 129
  • 5

2 Answers2

2

Is it something like that ?

library(lubridate)
months_since_1960 <- c(0, 1, 12, 13, 24, 25)
date_ref = as.Date("1960-01-01")
date_ref %m+% months(months_since_1960)

nimliug
  • 349
  • 1
  • 11
  • `lubridate` is definitely the right choice! Here's the [cheatsheet](https://rawgit.com/rstudio/cheatsheets/main/lubridate.pdf) to give OP a quick overview of the package – mfg3z0 Mar 03 '23 at 19:54
0

1) yearmon First create a yearmon variable which internally represents a date by year + fraction where fraction is 0, 1/12, ..., 11/12 for the 12 months. Then we can use that or convert to Date giving several possibilities.

library(zoo)
months_since_1960 <- c(0, 1, 12, 13, 24, 25)

ym <- as.yearmon(1960) + months_since_1960 / 12

ym # year and month
## [1] "Jan 1960" "Feb 1960" "Jan 1961" "Feb 1961" "Jan 1962" "Feb 1962"

as.Date(ym) # first of month
## [1] "1960-01-01" "1960-02-01" "1961-01-01" "1961-02-01" "1962-01-01" "1962-02-01"

as.Date(ym, frac = 1) # last of month
## [1] "1960-01-31" "1960-02-29" "1961-01-31" "1961-02-28" "1962-01-31" "1962-02-28"

2) Base R With base R (no packages) we can do this to get the first of the month:

dat <- months_since_1960 |>
  lapply(\(x) tail(seq(as.Date("1960-01-01"), length = x+1, by = "month"), 1)) |>
  do.call(what = "c")
dat
## [1] "1960-01-01" "1960-02-01" "1961-01-01" "1961-02-01" "1962-01-01" "1962-02-01"

or for last of of month

as.Date(cut(dat + 31, "month")) - 1
## [1] "1960-01-31" "1960-02-29" "1961-01-31" "1961-02-28" "1962-01-31" "1962-02-28"

2a) or this where we can use the same transformation to get end of month if desired:

dat2 <- as.Date(ISOdate(1960 + (months_since_1960 %/% 12), months_since_1960 %% 12 + 1, 1))
dat2 
## [1] "1960-01-01" "1960-02-01" "1961-01-01" "1961-02-01" "1962-01-01" "1962-02-01"
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341