Epidemiological curve using R and epitools gives wrong epiweeks - r

I have been trying to make epidemic curves in R with the epitools package. According to the documentation, you can automatically generate epidemiological weeks from a date variable, similar as I have been doing for long in STATA. Fyi, epidemiological weeks are different from yearly week numbers:
The first epi week of the year ends, by definition, on the first
Saturday of January, as long as it falls at least four days into the
month. Each epi week begins on a Sunday and ends on a Saturday.
http://www.cmmcp.org/epiweek.htm
https://wiki.ecdc.europa.eu/fem/f/1287/p/576/681.aspx#681
graphlabels<-epicurve.weeks(DATE_variable,
axisnames=FALSE,
xlab = "Week of Year",
ylab = "Cases per week",
tick.offset = 0.5,
col=mypalette)
axis(1,
at = graphlabels$xvals,
labels = graphlabels$cweek,
tick = FALSE,
line = 0,
)
This automatically generated a nice curve:
"Hurray!!", I thought. But, alas, being a scientist I double checked the data using STATA as well as manually and noticed that the data does not correspond!
Am I doing something wrong with epitool package that it gives me wrong epic weeks?

After some further discussion and research, there are differences in how epidemiological weeks can be calculated.
EPITOOLS as.week
In public health, reportable diseases are often reported by 'disease
week' (either week of reporting or week of symptom onset). In R, weeks
are numbered from 0 to 53 in the same year. The first day of week 1
starts with either the first Sunday or Monday of the year. Days before
week 1 are numbered as 0s. In contrast to R, the as.week function
generates weeks numbered from 1 to 53. The week before week 1 takes on
the value (52 or 53) from the last week of the previous year. The
as.week functions facilitates working with multiple years and
generating epidemic curves.
MMWR week
Values for MMWR week range from 1 to 53, although most years consist
of 52 weeks. 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.
EPIWEEK for STATA
Each epidemiological week begins on a Sunday and ends on Saturday. And
the first epidemiological week of year ends on the first Saturday of
January, provided that it falls at least four or more days into the
month
ISO (or business) week
An ISO week-numbering year (also called ISO year informally) has 52 or
53 full weeks. That is 364 or 371 days instead of the usual 365 or 366
days. The extra week is referred to here as a leap week, although ISO
8601 does not use this term. Weeks start with Monday. The first week
of a year is the week that contains the first Thursday of the year
Week "u" in SAS
Each epidemiological week begins on a Sunday and ends on Saturday. And
the first epidemiological week of year contains Sunday. Weeks range
from 0 to 53 but do not always count 7 days

Related

R not recognizing week number correctly [duplicate]

String contains 'YEAR WEEK' and I want to transform it with parse_date_time() to a date object but I can't make the code work:
parse_date_time(c("201510"), "YW")
I don't have to use lubridate, can be other packages, too.
Before converting year-week to a date you have to specify a day of the week but more importantly you have to ensure which of the different conventions is being used.
Base R's strptime() function knows 3 definitions of week of the year (but supports only 2 of them on input) and 2 definitions of weekday number,
see ?strptime:
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.
Converting year-week-day with the different conventions
If we append day 1 to the string and use the different formats we do get
as.Date("2015101", "%Y%U%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%U%w")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%w")
# [1] "2015-03-09"
as.Date("2015101", "%G%V%u")
# [1] NA
For weekday formats %u and %w we do get the same result because day 1 is Monday in both conventions (but watch out when dealing with Sundays).
For 2015, the US and the UK definition for week of the year coincide but this is not true for all years, e.g., not for 2001, 2007, and 2018:
as.Date("2018101", "%Y%U%u")
#[1] "2018-03-12"
as.Date("2018101", "%Y%W%u")
#[1] "2018-03-05"
The ISO 8601 format specifiers aren't supported on input. Therefore, I had created the ISOweek package some years ago:
ISOweek::ISOweek2date("2015-W10-1")
#[1] "2015-03-02"
Edit: Using Thursday to associate a week with a month
As mentioned above you need to specify a day of the week to get a full calendar date. This is also required if the dates need to be aggregated by month later on.
If no weekday is specified and if the dates are supposed to be aggregated by month later on, you may take the Thursday of each week as reference day (following a suggestion by djhurio). This ensures that the whole week is assigned to the month to which the majority of the days of the week belong to.
For example, taking Sunday as reference day would return
ISOweek::ISOweek2date("2015-W09-7")
[1] "2015-03-01"
which consequently would associate the whole week to the month of March although only one day of the week belongs to March while the other 6 days belong to February. Taking Thursday as reference day will return a date in February:
ISOweek::ISOweek2date("2015-W09-4")
[1] "2015-02-26"
Yes ISOweek package does this
ISOweek::ISOweek2date(isoWeek)
but for the other direction, check up the newer lubridate package as well
ISOweek::date2ISOweek(yourDate)
lubridate::isoweek(ymd(yourDate))

Yearweek is parsed wrongly in R

Problem: I am facing the problem that R parses a date (30 December 2019) into yearweek wrongly (Output: 2019 W01). I do not know why this is happening. Any suggestions what to change/alternative way of coding?
format(lubridate::ymd("2019-12-30"), "%Y W%V")
# Output
# 2019 W01
# Desired Output:
# 2019 W52
From the strptime documentation:
%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.
%V
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. (Accepted but ignored on input.)
%W
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). The UK
convention.
It sounds like you may want either %U or %W, depending on whether you want to treat Sunday or Monday as the start of the week.
Note however that these can result in values between 00 and 53, which is a consequence of fixing the start of the week to a particular weekday (either Sunday or Monday). Doing that means that there can actually be a partial week at the start and at the end of the year.
If you prefer to count based on week number 1 beginning on the first day of the year, you can use the function lubridate::week.
For example:
library(lubridate)
year_week <- function(date) paste0(year(date), ' W', week(date))
year_week(ymd("2019-01-01"))
# Result: "2019 W1"
year_week(ymd("2019-12-30"))
# Result: "2019 W52"
After some more research I found that this is the best solution:
format(lubridate::ymd("2019-12-30"), "%G W%V")
Use %G instead of %Y to reflect that the week-based year (%G and %g) may differ from the calendar year (%Y and %y).
See also: https://community.rstudio.com/t/converting-week-number-and-year-into-date/27202/2

Transform year/week to date object

String contains 'YEAR WEEK' and I want to transform it with parse_date_time() to a date object but I can't make the code work:
parse_date_time(c("201510"), "YW")
I don't have to use lubridate, can be other packages, too.
Before converting year-week to a date you have to specify a day of the week but more importantly you have to ensure which of the different conventions is being used.
Base R's strptime() function knows 3 definitions of week of the year (but supports only 2 of them on input) and 2 definitions of weekday number,
see ?strptime:
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.
Converting year-week-day with the different conventions
If we append day 1 to the string and use the different formats we do get
as.Date("2015101", "%Y%U%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%U%w")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%w")
# [1] "2015-03-09"
as.Date("2015101", "%G%V%u")
# [1] NA
For weekday formats %u and %w we do get the same result because day 1 is Monday in both conventions (but watch out when dealing with Sundays).
For 2015, the US and the UK definition for week of the year coincide but this is not true for all years, e.g., not for 2001, 2007, and 2018:
as.Date("2018101", "%Y%U%u")
#[1] "2018-03-12"
as.Date("2018101", "%Y%W%u")
#[1] "2018-03-05"
The ISO 8601 format specifiers aren't supported on input. Therefore, I had created the ISOweek package some years ago:
ISOweek::ISOweek2date("2015-W10-1")
#[1] "2015-03-02"
Edit: Using Thursday to associate a week with a month
As mentioned above you need to specify a day of the week to get a full calendar date. This is also required if the dates need to be aggregated by month later on.
If no weekday is specified and if the dates are supposed to be aggregated by month later on, you may take the Thursday of each week as reference day (following a suggestion by djhurio). This ensures that the whole week is assigned to the month to which the majority of the days of the week belong to.
For example, taking Sunday as reference day would return
ISOweek::ISOweek2date("2015-W09-7")
[1] "2015-03-01"
which consequently would associate the whole week to the month of March although only one day of the week belongs to March while the other 6 days belong to February. Taking Thursday as reference day will return a date in February:
ISOweek::ISOweek2date("2015-W09-4")
[1] "2015-02-26"
Yes ISOweek package does this
ISOweek::ISOweek2date(isoWeek)
but for the other direction, check up the newer lubridate package as well
ISOweek::date2ISOweek(yourDate)
lubridate::isoweek(ymd(yourDate))

girimi839y80904040mkrkellieimimdikiifirimKINOUBIGIAIIOVIubiuuiioioaa ufu Why do we saythat there 52 weeks in a year? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 years ago.
Improve this question
Am I crazy, I've always thought there were 52 weeks in a year, a check on google returns numerous results stating the same...
But if I create a simple spreadsheet, with column A containing 1 to 365 and column B containing INT(A1 / 7) repeated 365 times, column B contains the week index corresponding to the 'julian' day in column A.
The weeks go from 0 to 52, this is actually 53 weeks. If the 1st of January is on day 0, then the 31st of December must overlay into week 1 of the next year.
Can some help explain why we say 52 weeks and not 53?
Sorry I know this isn't strictly a coding question, but is is very relative to a lot of problems with dates and coding.
There are 52 complete weeks in a year. The year has 365 days, leaving one extra day. A leap year has 366 days, adding a second extra day. This makes 52 1/7 weeks in a normal year and 52 2/7 weeks in a leap year..
An ISO week-numbering year (also called ISO year informally) has 52 or 53 full weeks, that is 364 or 371 days instead of the usual 365 or 366 days. The extra week is sometimes referred to as a leap week, although ISO 8601 does not use this term.
The ISO week date system is effectively a leap week calendar system that is part of the ISO 8601 date and time standard issued by the (ISO) since 1988 and, before that, it was defined in ISO (R) 2015 since 1971. It is used (mainly) in government and business for fiscal years, as well as in timekeeping. This was previously known as "Industrial date coding". The system specifies a week year atop the Gregorian calendar by defining a notation for ordinal weeks of the year.
Weeks start with Monday. Each week's year is the Gregorian year in which the Thursday falls. The first week of the year, hence, always contains 4 January. ISO week year numbering therefore slightly deviates from the Gregorian for some days close to 1 January.

Calculating the number of weeks for each year based on dates using R

I have a dataset with dates of 2 different years (2009 and 2010) and would like to have the corresponding week number for each date.
My dataset is similar to this:
anim <- c(012,023,045,098,067)
dob <- c("01-09-2009","12-09-2009","22-09-2009","10-10-2010","28-10-2010")
mydf <- data.frame(anim,dob)
mydf
anim dob
1 12 01-09-2009
2 23 12-09-2009
3 45 22-09-2009
4 98 10-10-2010
5 67 28-10-2010
I would like to have variable "week" in the third column with the corresponding week numbers for each date.
EDIT:
Note: Week one begins on January 1st, week two begins on January 8th for each year
Any help would be highly appreciated.
Baz
Your definition of "week of year"
EDIT: Note: Week one begins on January 1st, week two begins on January 8th for each year
differs from the standard ones supported by strftime:
%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.
%W
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). The UK convention.
So you need to compute it based on the day-of-year number.
mydf$week <- (as.numeric(strftime(as.POSIXct(mydf$dob,
format="%d-%m-%Y"),
format="%j")) %/% 7) + 1
Post 2011 Answer
library(lubridate)
mydf$week <- week(mydf$week)
lubridate package is straight-forward for day-to-day tasks like this.
If you want to do how many weeks (or 7 day periods) have passed between your date of interest and the first day of the year, regardless of what day of the week it was on the first of the year, the following is a solution (using floor_date from lubridate).
mydf$weeks <- difftime(mydf$dob, floor_date(mydf$dob, "year"), units = c("weeks")))

Resources