我正在使用一个具有以下日期结构的数据集:
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格式。
答案 0 :(得分:1)
取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
如果您使用的是英语语言环境,则alternative可以写出星期几:
dow <- weekdays(as.Date("1950-01-01") + 0:6)
在示例中,两行的开始日期均为星期五。如果知道总是这样,我们可以通过将其硬编码为5来缩短代码:
transform(DF, Date = DateStart + (match(Day, dow) - 1 - 5) %% 7)
可重复输入的输入是:
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