I am struggling to convert week number and year into date. I used to do it with the MMWRweek package, and it worked just fine. However, I now always get NAs values.
For instance:
MMWRweek2Date(MMWRyear=2015,MMWRweek=36,MMWRday=3)
[1] NA
I tried to work around using another method, with the as.Date function. It works (I get a date), but I have 1 week lag.
Foir instance:
as.Date("2019-11-1", format ="%Y-%U-%u")
[1] "2019-03-18
While actually first day of week 11 of 2019 should be "2019-03-11".
It of course follows the convention mentioned in the documentation:
The first day of any MMWR week is Sunday. MMWR week numbering is sequential beginning with 1 and incrementing with each week to a maximum of 52 or 53. MMWR week #1 of an MMWR year is the first week of the year that has at least four days in the calendar year. For example, if January 1 occurs on a Sunday, Monday, Tuesday or Wednesday, the calendar week that includes January 1 would be MMWR week #1. If January 1 occurs on a Thursday, Friday, or Saturday, the calendar week that includes January 1 would be the last MMWR week of the previous year (#52 or #53). Because of this rule, December 29, 30, and 31 could potentially fall into MMWR week #1 of the following MMWR year.
I think you're experiencing the issue with as.Date because the way R counts the week numbers.
Here's from the documentation of strptime:
%u
Weekday as a decimal number (1–7, Monday is 1).
%U
Week of the year as decimal number (00–53) using Sunday as the first day 1 of the week (and typically with the first Sunday of the year as day 1 of week 1). The US convention.
Check this:
as.Date(x = "2019-1-1",
format = "%Y-%U-%u")
#> [1] "2019-01-07"
US convention : Week of the year as decimal number (00–53) using Sunday as the first day 1 of the week (and typically with the first Sunday of the year as day 1 of week 1): %U
UK convention : Week of the year as decimal number (00–53) using Monday as the first day of week (and typically with the first Monday of the year as day 1 of week 1): %W
ISO 8601 definition : Week of the year as decimal number (01–53) as defined in ISO 8601. If the week (starting on Monday) containing 1 January has four or more days in the new year, then it is considered week 1. Otherwise, it is the last week of the previous year, and the next week is week 1: %V which is accepted but ignored on input.
Note that there is also a week-based year ( %G and %g ) which is to be used with %V as it may differ from the calendar year ( %Y and %y ).
Numeric weekday
Weekday as a decimal number (1–7, Monday is 1): %u
Weekday as decimal number (0–6, Sunday is 0): %w
Interestingly, there is no format for the case Sunday is counted as day 1 of the week.
So two things here. First, definitely there is something wrong because the MMWRweek2Date function does not work. I tried again your example and it only returns NA. It used to work well on my previous computer (and previous R version), so maybe there is something to do with the current R Version ?
Secondly, I now understand why I get this 1 week lag with the as.Date().
It indeed relates to the fact that as.Date considers weeks from Sunday and not Monday. Consequently, the week starting Sunday 30 January 2018 is consider the last week of 2018, while the first week of 2019 starts on Sunday 6 Januray.
This is not convenient to me because I want my weeks to start on monday, thus Monday 31 January being my first year of 2019.
Anyway, I found another solution but quite laborious:
I created a variable such that my date appears in the format "%Y-W%V-%u" (eg, "2019-W01-1")
Then, I used the ISOweek2date() function.
Well, not very efficient but it works !
Thanks,
Héloïse
For a custom week definition, you might consider the lubridate package. In particular, using ceiling_date(first_day_of_year, unit = "week") to get the first Monday of the year, then first_monday + dweeks(input_week - 1) to get the date of the first Monday of that week.
library(lubridate)
input_year <- 2016:2018
input_week <- c(1, 17, 50)
input_day_of_week <- 1 # Monday
# if weeks are in the U.S. convention (@Yarnabrina's solution)
date_us_week <- as.Date(
paste(input_year, input_week, input_day_of_week),
format = "%Y %U %u"
)
date_us_week
#> [1] "2016-01-04" "2017-04-24" "2018-12-17"
wday(date_us_week, label = TRUE)
#> [1] Mon Mon Mon
#> Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
# for a custom week definition
first_day_of_year <- make_date(input_year)
first_monday_of_year <- ceiling_date(
first_day_of_year,
unit = "week",
week_start = 1,
change_on_boundary = FALSE
)
wday(first_monday_of_year, label = TRUE)
#> [1] Mon Mon Mon
#> Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
# week 1 starts on the first Monday, so it should be
# first_monday_of_year + dweeks(0)
(first_monday_of_week <- first_monday_of_year + dweeks(input_week - 1))
#> [1] "2016-01-04" "2017-04-24" "2018-12-10"
# if you care which day of the week it is, you'll have to add
# the correct number of days
first_monday_of_week + ddays(input_day_of_week - 1)
#> [1] "2016-01-04" "2017-04-24" "2018-12-10"
thanks for your input. Well, I tested it but it leads to the same result, that is starting week 1 of 2019 on Monday 7 January 2018. I would actually want that week to be the second week, and week from Monday 31 December 2018 to Sunday 6 January 2019 to be the first week.
My issue in in converting week number & year into date, but taking into account in the conversion that to me week 1 year 2019 will be from 31 December 2018 to 6 January 2019, and week 2 from 7 January 2019...and so on.
If you change ceiling_date() to floor_date() this might solve your problem (since you want the first week of 2019 to actually start at the end of 2018, on a Monday).
My exercise is to make a plot diagram according to date for different amounts. In my table, I have CalendarYear, CalendarWeeknumber and CalendarDay columns. I would like to merge all of it together as a date. I was trying use the MMWRweek package with the code:
But my problem is, that the the days are given as month dates (1-31) and for this function i would need them (1-7 as the week days). Does anybody know how to solve this problem?
Kind regards: Zsozsi