在一个时间间隔内匹配星期几以创建特定日期
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
取 Day
和 DateStart
的星期几之间的差模 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))
我正在处理一个日期结构如下的数据集:
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
取 Day
和 DateStart
的星期几之间的差模 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))