3

Let's say we have this:

ex <- c('2012-41')

This represent the week 41 from the year 2012. How would I get the month from this?

Since a week can be between two months, I will be interested to get the month when that week started (here October).

Not duplicate to How to extract Month from date in R (do not have a standard date format like %Y-%m-%d).

Andrei Niță
  • 517
  • 1
  • 3
  • 14
  • 2
    Try `format(as.Date(ex, "%Y-%W"), "%m")` – akrun Mar 05 '19 at 16:14
  • It could be that the week is between two months – LocoGris Mar 05 '19 at 16:15
  • 1
    This is not so exactly, because one week can be on two different months (past week, for example, started on February 24 (Sunday) and ended on March 02) – Iago Carvalho Mar 05 '19 at 16:16
  • thanks, indeed. Actually I wanted to do a column in a dataframe with the month in order to make a propper ggplot with x axis as Date. I aggregated data from daily to monthly using the format(tt$date, "%Y-%V"). I will modify the example – Andrei Niță Mar 05 '19 at 16:22
  • 1
    Possible duplicate of [How to extract Month from date in R](https://stackoverflow.com/questions/22603847/how-to-extract-month-from-date-in-r) – divibisan Mar 05 '19 at 16:30
  • 1
    Possible duplicate of [How to Parse Year + Week Number in R?](https://stackoverflow.com/questions/9380435/how-to-parse-year-week-number-in-r) – divibisan Mar 05 '19 at 16:38
  • 1
    ^ Combine those 2 duplicates to get your answer – divibisan Mar 05 '19 at 16:40
  • @dww Good idea, but it doesn't work. The result of that code is 3, i.e. March, instead of 10 for October. – RHertel Mar 06 '19 at 07:59

3 Answers3

3

you could try:

ex <- c('2019-10')

splitDate <- strsplit(ex, "-")

dateNew <- as.Date(paste(splitDate[[1]][1], splitDate[[1]][2], 1, sep="-"), "%Y-%U-%u")

monthSelected <- lubridate::month(dateNew)

3

I hope this helps!

OTStats
  • 1,820
  • 1
  • 13
  • 22
Raul Guerrero
  • 388
  • 2
  • 10
1

This depends on the definition of week. See the discussion of %V and %W in ?strptime for two possible definitions of week. We use %V below but the function allows one to specify the other if desired. The function performs a sapply over the elements of x and for each such element it extracts the year into yr and forms a sequence of all dates for that year in sq. It then converts those dates to year-month and finds the first occurrence of the current component of x in that sequence, finally extracting the match's month.

yw2m <- function(x, fmt = "%Y-%V") {
  sapply(x, function(x) {
    yr <- as.numeric(substr(x, 1, 4))
    sq <- seq(as.Date(paste0(yr, "-01-01")), as.Date(paste0(yr, "-12-31")), "day")
    as.numeric(format(sq[which.max(format(sq, fmt) == x)], "%m"))
  })
}

yw2m('2012-41')
## [1] 10
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
0

The following will add the week-of-year to an input of year-week formatted strings and return a vector of dates as character. The lubridate package weeks() function will add the dates corresponding to the end of the relevant week. Note for example I've added an additional case in your 'ex' variable to the 52nd week, and it returns Dec-31st

library(lubridate)

ex <- c('2012-41','2016-4','2018-52')

dates <- strsplit(ex,"-")
dates <- sapply(dates,function(x) {
  year_week <- unlist(x)
  year <- year_week[1]
  week <- year_week[2]
  start_date <- as.Date(paste0(year,'-01-01'))
  date <- start_date+weeks(week)
  #note here: OP asked for beginning of week.  
  #There's some ambiguity here, the above is end-of-week; 
  #uncommment here for beginning of week, just subtracted 6 days.  
  #I think this might yield inconsistent results, especially year-boundaries
  #hence suggestion to use end of week.  See below for possible solution
  #date <- start_date+weeks(week)-days(6)

  return (as.character(date))
})

Yields:

> dates
[1] "2012-10-14" "2016-01-29" "2018-12-31"

And to simply get the month from these full dates:

month(dates)

Yields:

> month(dates)
[1] 10  1 12
Soren
  • 1,792
  • 1
  • 13
  • 16