Identify dates in the same week
This will assign a unique integer to groups of dates that fall within a given week:
origin <- as.Date("2012-12-9") ## A Sunday
weekID <- as.numeric(exampleDates - origin) %/% 7
data.frame(date = exampleDates,
weekday = weekdays(exampleDates),
week = weekID)
# date weekday week
# 1 2012-12-26 Wednesday 2
# 2 2012-12-27 Thursday 2
# 3 2012-12-28 Friday 2
# 4 2012-12-29 Saturday 2
# 5 2012-12-30 Sunday 3
# 6 2012-12-31 Monday 3
# 7 2013-01-01 Tuesday 3
# 8 2013-01-02 Wednesday 3
# 9 2013-01-03 Thursday 3
# 10 2013-01-04 Friday 3
# 11 2013-01-05 Saturday 3
# 12 2013-01-06 Sunday 4
# 13 2013-01-07 Monday 4
# 14 2013-01-08 Tuesday 4
# 15 2013-01-09 Wednesday 4
Find the day of a week
df = data.frame(date=c("2012-02-01", "2012-02-01", "2012-02-02"))
df$day <- weekdays(as.Date(df$date))
df
## date day
## 1 2012-02-01 Wednesday
## 2 2012-02-01 Wednesday
## 3 2012-02-02 Thursday
Edit: Just to show another way...
The wday
component of a POSIXlt
object is the numeric weekday (0-6 starting on Sunday).
as.POSIXlt(df$date)$wday
## [1] 3 3 4
which you could use to subset a character vector of weekday names
c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday")[as.POSIXlt(df$date)$wday + 1]
## [1] "Wednesday" "Wednesday" "Thursday"
Aggregate week and date in R by some specific rules
First we can convert the dates in df2
into year-month-date format, then join the two tables:
library(dplyr);library(lubridate)
df2$dt = ymd(df2$date)
df2$wk = day(df2$dt) %/% 7 + 1
df2$year_month_week = as.numeric(paste0(format(df2$dt, "%Y%m"), df2$wk))
df1 %>%
left_join(df2 %>% group_by(year_month_week) %>% slice(1) %>%
select(year_month_week, temperature))
Result
Joining, by = "year_month_week"
id year_month_week points temperature
1 1 2022051 65 36.1
2 1 2022052 58 36.6
3 1 2022053 47 NA
4 2 2022041 21 34.3
5 2 2022042 25 34.9
6 2 2022043 27 NA
7 2 2022044 43 NA
Convert week number to date
as.Date
is calling the 1 to 9 as NA as it is expects two digits for the week number and can't properly parse it.
To fix it, add in some - to split things up:
as.Date(paste(2014, df$Week, 1, sep="-"), "%Y-%U-%u")
Generate dates based on a date column -same day of week, same month
We can convert the 'indexdt' to Date
class, loop over the elements, get a seq
uence of dates with the end specified as the end of the month with ceiling_date
(from lubridate
) and specify by
as "week" in a list
and then unnest
the list
column
library(dplyr)
library(purrr)
library(lubridate)
library(tidyr)
df1 %>%
mutate(indexdt = as.Date(indexdt, "%m-%d-%Y"),
date = map(indexdt, ~ seq(.x, ceiling_date(.x, 'month'),
by = 'week')[-1])) %>%
unnest(c(date))
Or using data.table
library(data.table)
setDT(df1)[, indexdt := as.Date(indexdt, "%m-%d-%Y")]
df1[, .(date = seq(indexdt, ceiling_date(indexdt, "month"),
by = "week")[-1]), .(indexdt)]
For 2020, add one year
df1 %>%
mutate(indexdt = as.Date(indexdt, "%m-%d-%Y"),
date = map(indexdt, ~ seq(.x + years(1),
ceiling_date(.x + years(1), 'month'), by = 'week')[-1])) %>%
unnest(c(date))
with data.table
df1[, .(date = seq(indexdt, ceiling_date(indexdt +years(1), "month"),
by = "week")[-1]), .(indexdt)]
data
df1 <- structure(list(indexdt = c("01-02-2019", "08-15-2019")), class = "data.frame", row.names = c(NA,
-2L))
R: Round down dates to first day of the week
cut()
from base R has two methods for objects of class Date
and POSIXt
which assume that weeks start on Monday by default (but may be changed to Sunday using start.on.monday = FALSE
).
dates <- c("2016-04-04", "2016-04-05", "2016-04-06", "2016-04-07", "2016-04-08",
"2016-04-09", "2016-04-10", "2016-04-11", "2016-04-12", "2016-04-13",
"2016-04-14")
result <- data.frame(
dates,
cut_Date = cut(as.Date(dates), "week"),
cut_POSIXt = cut(as.POSIXct(dates), "week"),
stringsAsFactors = FALSE)
result
# dates cut_Date cut_POSIXt
#1 2016-04-04 2016-04-04 2016-04-04
#2 2016-04-05 2016-04-04 2016-04-04
#3 2016-04-06 2016-04-04 2016-04-04
#4 2016-04-07 2016-04-04 2016-04-04
#5 2016-04-08 2016-04-04 2016-04-04
#6 2016-04-09 2016-04-04 2016-04-04
#7 2016-04-10 2016-04-04 2016-04-04
#8 2016-04-11 2016-04-11 2016-04-11
#9 2016-04-12 2016-04-11 2016-04-11
#10 2016-04-13 2016-04-11 2016-04-11
#11 2016-04-14 2016-04-11 2016-04-11
Note that cut()
returns factors which is perfect for aggregation as requested by the OP:
str(result)
#'data.frame': 11 obs. of 3 variables:
# $ dates : chr "2016-04-04" "2016-04-05" "2016-04-06" "2016-04-07" ...
# $ cut_Date : Factor w/ 2 levels "2016-04-04","2016-04-11": 1 1 1 1 1 1 1 2 2 2 ...
# $ cut_POSIXt: Factor w/ 2 levels "2016-04-04","2016-04-11": 1 1 1 1 1 1 1 2 2 2 ...
However, for plotting aggregated values with ggplot2
(and if there is a large number of weeks which might clutter the axis) it might be better to switch from a discrete time scale to a continuous time scale. Then it is necessary to coerce factors back to Date
or POSIXct
:
as.Date(as.character(result$cut_Date))
as.POSIXct(as.character(result$cut_Date))
Get the difference between dates in terms of weeks, months, quarters, and years
what about this:
# get difference between dates `"01.12.2013"` and `"31.12.2013"`
# weeks
difftime(strptime("26.03.2014", format = "%d.%m.%Y"),
strptime("14.01.2013", format = "%d.%m.%Y"),units="weeks")
Time difference of 62.28571 weeks
# months
(as.yearmon(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearmon(strptime("14.01.2013", format = "%d.%m.%Y")))*12
[1] 14
# quarters
(as.yearqtr(strptime("26.03.2014", format = "%d.%m.%Y"))-
as.yearqtr(strptime("14.01.2013", format = "%d.%m.%Y")))*4
[1] 4
# years
year(strptime("26.03.2014", format = "%d.%m.%Y"))-
year(strptime("14.01.2013", format = "%d.%m.%Y"))
[1] 1
as.yearmon()
and as.yearqtr()
are in package zoo
. year()
is in package lubridate
.
What do you think?
How to get week starting date from a date in R
Use the floor_date
function from the lubridate
package.
library("lubridate")
floor_date(as.Date("04/20/2017", "%m/%d/%Y"), unit="week")
Related Topics
How to Extract Text from R's Help Command
Caret Error: "All the Accuracy Metric Values Are Missing"
R: Calculate the Number of Occurrences of a Specific Event in a Specified Time Future
Annotation_Custom with Npc Coordinates in Ggplot2
How to Load Any Package in R (Unable to Load Shared Object)
Change Date Print Format from Yyyy-Mm-Dd to Dd-Mm-Yyyy
How to Place an Identical Smooth on Each Facet of a Ggplot2 Object
Color Bar Missing in Ggplot Legend, Windows Remote Desktop
Return Call from Ggplot Object
Preventing Incosistent Spacing/Bar Widths in Geom_Bar with Many Bars
How to Avoid Density Curve Getting Cut Off in Plot
Ordering Factors in Each Facet of Ggplot by Y-Axis Value
Splitting Text to Words with R and Csplit()
Fread and a Quoted Multi-Line Column Value
How to Plot a Boxplot with Correctly Spaced Continuous X-Axis Values in Ggplot2