在一个时间间隔内匹配星期几以创建特定日期

Match Days of the Week within an Interval to Create Specific Dates

我正在处理一个日期结构如下的数据集:

Week  DateStart    DateEnd      Day
1     5-Aug-16     11-Aug-16    Monday
2     12-Aug-16    18-Aug-16    Thursday

其中"Week"对应学习周数,"DateStart"和"DateEnd"是该周的第一天和最后一天,"Day"表示从在那一周内。我想使用 "DateStart"、"DateEnd" 和 "Day" 字段创建一个新字段 "Date",为每个 "Day" 分配一个特定日期落在 "DateStart" 和 "DateEnd" 区间内。

我已经使用 %--% 运算符将 DateStart 和 DateEnd 转换为一个间隔:

Week_Interval <- DateStart %--% DateEnd

但是后来我不太幸运地弄清楚了如何将 Day 字段与结果间隔内的日期相匹配。我试过通读 lubridate 文档,但似乎没有任何内容可以专门解决我的问题。我希望这里有人可能对此有一些经验,可以帮助我指明正确的方向。

我理想的输出是这样的:

Week  DateStart    DateEnd      Day        Date
1     5-Aug-16     11-Aug-16    Monday     08-08-2016
2     12-Aug-16    18-Aug-16    Thursday   18-08-2016

日期遵循标准的 dd-mm-yyyy 格式。

# example data
df = read.table(text = "
Week  DateStart    DateEnd      Day
1     5-Aug-16     11-Aug-16    Monday
2     12-Aug-16    18-Aug-16    Thursday
", header=T, stringsAsFactors=F)

library(tidyverse)
library(lubridate)

df %>%
  group_by(Week, Day) %>%               # for each week and day
  mutate(Date = list(seq(dmy(DateStart), dmy(DateEnd), "1 day")),  # get sequence of dates between start and end
         Day2 = map(Date, weekdays)) %>%                           # get name of days for each date in the sequence
  unnest() %>%                          # unnest dates
  ungroup() %>%                         # forget the grouping
  filter(Day == Day2) %>%               # keep days that match
  select(-Day2)                         # remove unnecessary column

# # A tibble: 2 x 5
#    Week DateStart DateEnd   Day      Date      
#   <int> <chr>     <chr>     <chr>    <date>    
# 1     1 5-Aug-16  11-Aug-16 Monday   2016-08-08
# 2     2 12-Aug-16 18-Aug-16 Thursday 2016-08-18

取 ​​DayDateStart 的星期几之间的差模 7,并将其添加到 DateStart

没有使用包。

dow <- c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
transform(DF, Date = 
  DateStart + (match(Day, dow) - 1 - as.POSIXlt(DateStart)$wday) %% 7)

给予:

  Week  DateStart    DateEnd      Day       Date
1    1 2016-08-05 2016-08-11   Monday 2016-08-08
2    2 2016-08-12 2016-08-18 Thursday 2016-08-18

注释 1

一个 alternative 写出星期几,如果你在英语语言环境中,是:

dow <- weekdays(as.Date("1950-01-01") + 0:6)

注2

在示例中,两行的开始日期都是星期五。如果知道情况总是如此,我们可以通过将其硬编码为 5:

来缩短代码
transform(DF, Date = DateStart + (match(Day, dow) - 1 - 5) %% 7)

注3

可重现形式的输入是:

Lines <- "Week  DateStart    DateEnd      Day
1     5-Aug-16     11-Aug-16    Monday
2     12-Aug-16    18-Aug-16    Thursday"
DF <- read.table(text = Lines, header = TRUE)
fmt <- "%d-%b-%y"
DF <- transform(DF, DateStart = as.Date(DateStart, fmt),
  DateEnd = as.Date(DateEnd, fmt))