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

时间:2018-08-19 15:39:31

标签: r lubridate

我正在使用一个具有以下日期结构的数据集:

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

其中“周”对应于学习周编号,“日期开始”和“日期结束”是该周的第一天和最后一天,“天”表示该周内的特定日期。我想使用“ DateStart”,“ DateEnd”和“ Day”字段创建一个新字段“ Date”,该字段为“ DateStart”和“ DateEnd”中的每个“ Day”分配一个特定的日期间隔。

我已经使用%-%运算符将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格式。

2 个答案:

答案 0 :(得分:1)

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))

答案 1 :(得分:0)

# 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