Converting week number and year into date

#1

Hello community!

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

Any help would be appreciated, thanks !
Héloïse

0 Likes

Merge Year, Week(0-53) and Days(1-31) as date problem
#2

Welcome to the community!

I haven't used MMWRweek package before, but it seems to work:

MMWRweek::MMWRweek2Date(MMWRyear = 2015,
                        MMWRweek = 36,
                        MMWRday = 3)
#> [1] "2015-09-08"

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"

Created on 2019-03-28 by the reprex package (v0.2.1)

I'm adding an excerpt from this SO post:

Week of the year

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

Hope this helps.

0 Likes

#3

Hey Yarnabrina,

thanks for your reply!

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

0 Likes

#4

I'm using R 3.5.3, and the version of the MMWRweek package is 0.1.1.

I guess this is from ISOweek package.

If your problem is solved (even if by you), will you please consider marking this thread to be solved?

If you don't know how, please take a look at this post:

0 Likes

#5

This is so strange, I use the same. Any idea where the problem might come from?

I will do so, should I open another thread for the MMWRweek package issue?

Thanks,
Héloïse

0 Likes

#6

No, I've no idea. I just tried to run again copying from your code, and it worked. You may try once again after restarting R, or trying directly in R instead of RStudio.

This is very confusing for me. I suggest you to close this topic as marking your solution and open a new topic referring to this one. Then, if the moderators feel that's unnecessary, they can merge the two threads.

0 Likes

#7

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"

Created on 2019-03-28 by the reprex package (v0.2.1)

0 Likes

#8

Hello Paleolimbot,

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.

Thanks,
Héloïse

0 Likes

#9

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

0 Likes

#10

Dear Everybody,

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:

MMWRweek2Date(CalendarYear,CalendarWeekNumber,CalendarDay)

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

1 Like

#11

Hi Paleolimbot,

perfect, it does work !

So a quick recap for those interested:

week year

1 1 2019
2 2 2019
3 3 2019
4 4 2019
5 5 2019
6 6 2019
7 7 2019
8 8 2019
9 9 2019
10 10 2019
11 11 2019

#date for the year under consideration
df$input_year <-make_date(df$year)

#setting customized first monday of the year
df$first_monday_of_year <- floor_date(df$input_year,
unit = "week",
week_start = 1)

#date (first monday of the week)
df$first_monday_of_week <- df$first_monday_of_year + dweeks(df$week - 1)

week year first_monday_of_week

1 1 2019 2018-12-31
2 2 2019 2019-01-07
3 3 2019 2019-01-14
4 4 2019 2019-01-21
5 5 2019 2019-01-28
6 6 2019 2019-02-04
7 7 2019 2019-02-11
8 8 2019 2019-02-18
9 9 2019 2019-02-25
10 10 2019 2019-03-04
11 11 2019 2019-03-11

I found it somehow as labour intensive as the work around with ISOweek, but definitely more "clean".

Thanks !
Héloïse

0 Likes

closed #12

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.

0 Likes