The day in which a week starts differs depending on context. For countries like the UK, the first day of the week is the first working day, which is Monday. This definition conforms with the ISO 8601 standard definition for the begining of a week, but there are examples of situations where the first day of the week is different:
This package provides tools to convert dates to weeks and back where a week can start on any day. You can use this package for any of the following:
date2week()
You can convert dates to weeks starting on any day by using date2week()
with the week_start
argument. This argument can be a number from 1 to 7 representing the ISO 8601 day of the week OR it can be a string representing the day of the week in either an English locale or the locale defined on your computer.
library("aweek")
set.seed(2019-03-03)
dat <- as.Date("2019-03-03") + sample(-6:7, 10, replace = TRUE)
dat
## [1] "2019-03-03" "2019-03-10" "2019-03-07" "2019-03-07" "2019-02-28"
## [6] "2019-03-07" "2019-03-09" "2019-03-08" "2019-03-10" "2019-03-08"
## <aweek start: Sunday>
## [1] "2019-W10-1" "2019-W11-1" "2019-W10-5" "2019-W10-5" "2019-W09-5"
## [6] "2019-W10-5" "2019-W10-7" "2019-W10-6" "2019-W11-1" "2019-W10-6"
## <aweek start: Sunday>
## [1] "2019-W10-1" "2019-W11-1" "2019-W10-5" "2019-W10-5" "2019-W09-5"
## [6] "2019-W10-5" "2019-W10-7" "2019-W10-6" "2019-W11-1" "2019-W10-6"
What you get back is an aweek
class object. It can be converted back to a date with either as.Date()
or week2date()
:
## [1] "2019-03-03" "2019-03-10" "2019-03-07" "2019-03-07" "2019-02-28"
## [6] "2019-03-07" "2019-03-09" "2019-03-08" "2019-03-10" "2019-03-08"
aweek
classThe result you see above is an object of class “aweek”. The aweek
class is a character that contains the week_start
attribute. This attribute allows it to be easily converted back to a date without the user needing to enter the start day every time. It can be created like so:
## <aweek start: Sunday>
## [1] "2019-W10-1"
## [1] "aweek"
If you need to remove the class, you can just use as.character()
:
## [1] "2019-W10-1"
The date2week()
function only checks that dates are in ISO 8601 (yyyy-mm-dd) format before converting to weeks, and otherwise assumes that the dates are accurate so it’s strongly recommended to make sure your dates are in either Date
or POISXt
format and accurate before converting to weeks. The lubridate can be used for this purpose.
Because the week_start
arguments default to ISO week day 1 (Monday), it’s recommended to specify week_start
in date2week()
and week2date()
if you don’t have an aweek
object.
Before you combine aweek objects, confirm that they are actually aweek objects with inherits(myObject, "aweek")
.
There are times where you would want to aggregate your days into weeks, you can do this by specifying floor_day = TRUE
in date2week()
. For example, here we can show the individual weeks:
## <aweek start: Saturday>
## [1] "2019-W10" "2019-W11" "2019-W10" "2019-W10" "2019-W09" "2019-W10"
## [7] "2019-W11" "2019-W10" "2019-W11" "2019-W10"
## wf
## 2019-W09 2019-W10 2019-W11
## 1 6 3
If you convert this to date, then all the dates will represent the beginning of the week:
## [1] "2019-03-02" "2019-03-09" "2019-03-02" "2019-03-02" "2019-02-23"
## [6] "2019-03-02" "2019-03-09" "2019-03-02" "2019-03-09" "2019-03-02"
## [1] "Saturday" "Saturday" "Saturday" "Saturday" "Saturday" "Saturday"
## [7] "Saturday" "Saturday" "Saturday" "Saturday"
Weeks can be represented as factors, which is useful for tabulations across weeks. You can use factor = TRUE
in date2week()
and it will automatically fill in any missing days (floor_day = FALSE
) or weeks (floor_day = TRUE
)
## <aweek start: Monday>
## [1] 2019-W09-7 2019-W12-1
## 16 Levels: 2019-W09-7 2019-W10-1 2019-W10-2 2019-W10-3 ... 2019-W12-1
## <aweek start: Monday>
## [1] 2019-W09 2019-W12
## Levels: 2019-W09 2019-W10 2019-W11 2019-W12
You can also use date2week()
to convert between different week definitions if you have an aweek
object:
## <aweek start: Sunday>
## [1] "2019-W10-1" "2019-W11-1" "2019-W10-5" "2019-W10-5" "2019-W09-5" "2019-W10-5" "2019-W10-7"
## [8] "2019-W10-6" "2019-W11-1" "2019-W10-6"
## <aweek start: Wednesday>
## [1] "2019-W09-5" "2019-W10-5" "2019-W10-2" "2019-W10-2" "2019-W09-2" "2019-W10-2" "2019-W10-4"
## [8] "2019-W10-3" "2019-W10-5" "2019-W10-3"
# create a table with all days in the week
d <- dat[1] + 0:6
res <- as.data.frame(matrix("", nrow = 7, ncol = 7), stringsAsFactors = FALSE)
names(res) <- weekdays(d) # days of the week
for (i in names(res)) res[[i]] <- date2week(d, week_start = i)
res
## Sunday Monday Tuesday Wednesday Thursday Friday Saturday
## 1 2019-W10-1 2019-W09-7 2019-W09-6 2019-W09-5 2019-W09-4 2019-W09-3 2019-W10-2
## 2 2019-W10-2 2019-W10-1 2019-W09-7 2019-W09-6 2019-W09-5 2019-W09-4 2019-W10-3
## 3 2019-W10-3 2019-W10-2 2019-W10-1 2019-W09-7 2019-W09-6 2019-W09-5 2019-W10-4
## 4 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W09-7 2019-W09-6 2019-W10-5
## 5 2019-W10-5 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W09-7 2019-W10-6
## 6 2019-W10-6 2019-W10-5 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W10-7
## 7 2019-W10-7 2019-W10-6 2019-W10-5 2019-W10-4 2019-W10-3 2019-W10-2 2019-W11-1
All of these columns contain the same dates:
## Sunday Monday Tuesday Wednesday Thursday Friday
## 1 2019-03-03 2019-03-03 2019-03-03 2019-03-03 2019-03-03 2019-03-03
## 2 2019-03-04 2019-03-04 2019-03-04 2019-03-04 2019-03-04 2019-03-04
## 3 2019-03-05 2019-03-05 2019-03-05 2019-03-05 2019-03-05 2019-03-05
## 4 2019-03-06 2019-03-06 2019-03-06 2019-03-06 2019-03-06 2019-03-06
## 5 2019-03-07 2019-03-07 2019-03-07 2019-03-07 2019-03-07 2019-03-07
## 6 2019-03-08 2019-03-08 2019-03-08 2019-03-08 2019-03-08 2019-03-08
## 7 2019-03-09 2019-03-09 2019-03-09 2019-03-09 2019-03-09 2019-03-09
## Saturday
## 1 2019-03-03
## 2 2019-03-04
## 3 2019-03-05
## 4 2019-03-06
## 5 2019-03-07
## 6 2019-03-08
## 7 2019-03-09
aweek
objectsYou can combine aweek objects with different week_start
attributes. The resulting aweek
object will have the same week_start
as the first object.
## <aweek start: Sunday>
## [1] "2019-W10-1" "2019-W10-2" "2019-W10-3"
## <aweek start: Tuesday>
## [1] "2019-W09-6" "2019-W09-7" "2019-W10-1"
You can also add dates to aweek objects:
## <aweek start: Monday>
## [1] "2019-W09-7" "2019-W10-1" "2019-W10-2" "2019-W10-3" "2019-W10-4"
## [6] "2019-W10-5" "2019-W10-6" "2019-W14-3"
You can also add character representation of weeks, but be aware that it is assumed that these have the same week_start
as the first object.
## <aweek start: Saturday>
## [1] "2019-W10-2" "2019-W10-3" "2019-W10-4" "2019-W10-5" "2019-W10-6"
## [6] "2019-W10-7" "2019-W11-1" "2019-W14-3"
## <aweek start: Monday>
## [1] "2019-W09-7" "2019-W10-1" "2019-W10-2" "2019-W10-3" "2019-W10-4"
## [6] "2019-W10-5" "2019-W10-6" "2019-W14-3"
These will translate into different dates
## [1] "2019-03-09" "2019-04-01"
## [1] "2019-03-09" "2019-04-03"
week2date()
If you receive data that contains week definitions, you can convert it back to a date if you know where the week starts.
## [1] "2019-03-03"
## [1] "2019-03-04"
If you have an aweek
object, however, it will use the week_start
attribute defined in the object:
## [1] "2019-03-03" "2019-03-10" "2019-03-07" "2019-03-07" "2019-02-28"
## [6] "2019-03-07" "2019-03-09" "2019-03-08" "2019-03-10" "2019-03-08"
You can also use as.Date()
and as.POISXlt()
if you have an aweek
object:
## [1] "2019-03-03" "2019-03-10" "2019-03-07" "2019-03-07" "2019-02-28"
## [6] "2019-03-07" "2019-03-09" "2019-03-08" "2019-03-10" "2019-03-08"
## [1] "2019-03-03 GMT" "2019-03-10 GMT" "2019-03-07 GMT" "2019-03-07 GMT"
## [5] "2019-02-28 GMT" "2019-03-07 GMT" "2019-03-09 GMT" "2019-03-08 GMT"
## [9] "2019-03-10 GMT" "2019-03-08 GMT"