I have a df with year and day of year as columns:

dat <- data.frame(year = rep(1980:2015, each = 365), day = rep(1:365,times = 36))

Please note that I am assuming 365 days in a year even if it is a leap year. I need to generate two things:

1) month 2) date

I did this:

# this tells me how many days in each month  
months <- list(1:31, 32:59, 60:90, 91:120, 121:151, 152:181, 182:212, 213:243, 244:273, 274:304, 305:334, 335:365)

library(dplyr)
# this assigns each day to a month
dat1 <- dat %>% mutate(month = sapply(day, function(x) which(sapply(months, function(y) x %in% y))))

I want to produce a third column which is a date in the format year,month,day. However, since I am assuming all years are non-leap years, I need to ensure that my dates also reflect this i.e. there should be no date as 29th Feb.

The reason I need to generate the date is because I want to generate number of 15 days period of a year. A year will have 24 15-days period

    1st Jan - 15th Jan: 1 period 
    16th Jan- 31st Jan: 2 period 
    1st Feb - 15th Feb: 3 period....
    16th till 31st dec: 24th period)

I need dates to specify whether a day in a month falls in the first half (i.e.d day <= 15) or second quarter (day > 15). I use the following script to do this:

dat2 <- dat1 %>% mutate(twowk = month*2 - (as.numeric(format(date,"%d")) <= 15))

In order for me to run this above line, I need to generate date and hence my question.

score:3

Accepted answer

A possible solution:

dat$dates <- as.Date(paste0(dat$year,'-',
                            format(strptime(paste0('1981-',dat$day), '%Y-%j'),
                                   '%m-%d'))
                     )

What this does:

  • With strptime(paste0('1981-',dat$day), '%Y-%j') you get the dates of a non-leap year.
  • By embedding that in format with '%m-%d' you extract the month and the day in the month.
  • paste that together with the year in the year-column and wrap that in as.Date to get a non-leap-year date.