简体   繁体   中英

Get the month from the week of the year

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).

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!

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM