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"
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"
## [6] "2019-W10-5" "2019-W10-7" "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"
## [6] "2019-W10-2" "2019-W10-4" "2019-W10-3" "2019-W10-5" "2019-W10-3"
# create a table with all days in the week
res <- as.data.frame(matrix("", nrow = 10, ncol = 7), stringsAsFactors = FALSE)
names(res) <- c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
for (i in names(res)) res[[i]] <- date2week(w, week_start = i)
as.data.frame(res)
## Mon Tue Wed Thu Fri Sat
## 1 2019-W09-7 2019-W09-6 2019-W09-5 2019-W09-4 2019-W09-3 2019-W10-2
## 2 2019-W10-7 2019-W10-6 2019-W10-5 2019-W10-4 2019-W10-3 2019-W11-2
## 3 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W09-7 2019-W10-6
## 4 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W09-7 2019-W10-6
## 5 2019-W09-4 2019-W09-3 2019-W09-2 2019-W09-1 2019-W08-7 2019-W09-6
## 6 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W09-7 2019-W10-6
## 7 2019-W10-6 2019-W10-5 2019-W10-4 2019-W10-3 2019-W10-2 2019-W11-1
## 8 2019-W10-5 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W10-7
## 9 2019-W10-7 2019-W10-6 2019-W10-5 2019-W10-4 2019-W10-3 2019-W11-2
## 10 2019-W10-5 2019-W10-4 2019-W10-3 2019-W10-2 2019-W10-1 2019-W10-7
## Sun
## 1 2019-W10-1
## 2 2019-W11-1
## 3 2019-W10-5
## 4 2019-W10-5
## 5 2019-W09-5
## 6 2019-W10-5
## 7 2019-W10-7
## 8 2019-W10-6
## 9 2019-W11-1
## 10 2019-W10-6
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 UTC" "2019-03-10 UTC" "2019-03-07 UTC" "2019-03-07 UTC"
## [5] "2019-02-28 UTC" "2019-03-07 UTC" "2019-03-09 UTC" "2019-03-08 UTC"
## [9] "2019-03-10 UTC" "2019-03-08 UTC"