我有一个相当大的数据框,其中包含一列POSIXct日期时间(每小时数据约为10年)。我会在夏令时期间标记当天所有的行。例如,如果夏令时开始于' 2000-04-02 03:00:00' (DOY = 93)我希望DOY = 93的前两个小时可以被标记。 虽然我是dplyr的新手,但我会尽可能地使用这个包,并尽可能避免 for-loops
例如:
library(lubridate)
sd = ymd('2000-01-01',tz="America/Denver")
ed = ymd('2005-12-31',tz="America/Denver")
span = data.frame(date=seq(from=sd,to=ed, by="hour"))
span$YEAR = year(span$date)
span$DOY = yday(span$date)
span$DLS = dst(span$date)
要查找应用夏令时的一年中的不同日期,请使用dplyr
library(dplyr)
limits = span %.% group_by(YEAR) %.% summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS]))
这给了
YEAR minDOY maxDOY
1 2000 93 303
2 2001 91 301
3 2002 97 300
4 2003 96 299
5 2004 95 305
6 2005 93 303
现在我会管道'上面的结果是 span 数据帧,而没有使用低效的 for-loop 。
在@aosmith的帮助下,只需两个命令即可解决问题(并避免使用'解决方案2'中的inner_join):
limits = span %>% group_by(YEAR) %>% mutate(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS]),CHECK=FALSE)
limits$CHECK[(limits2$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE
在@beetroot和@ matthew-plourde的帮助下,问题已经解决: 缺少内部联接:
limits = span %>% group_by(YEAR) %>% summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS])) %>% inner_join(span, by='YEAR')
然后我添加了一个新列(CHECK)来填充Daylight-savings days的正确值
limits$CHECK = FALSE
limits$CHECK[(limits$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE
答案 0 :(得分:8)
正如@beetroot在评论中指出的那样,您可以通过加入来实现这一目标:
limits = span %>%
group_by(YEAR) %>%
summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS])) %>%
inner_join(span, by='YEAR')
# YEAR minDOY maxDOY date DOY DLS
# 1 2000 93 303 2000-01-01 00:00:00 1 FALSE
# 2 2000 93 303 2000-01-01 01:00:00 1 FALSE
# 3 2000 93 303 2000-01-01 02:00:00 1 FALSE
# 4 2000 93 303 2000-01-01 03:00:00 1 FALSE
# 5 2000 93 303 2000-01-01 04:00:00 1 FALSE
# 6 2000 93 303 2000-01-01 05:00:00 1 FALSE
# 7 2000 93 303 2000-01-01 06:00:00 1 FALSE
# 8 2000 93 303 2000-01-01 07:00:00 1 FALSE
# 9 2000 93 303 2000-01-01 08:00:00 1 FALSE
# 10 2000 93 303 2000-01-01 09:00:00 1 FALSE
答案 1 :(得分:2)
dplyr是一个很棒的工具,但在这种情况下,我不确定它是最适合这份工作的。这完成了你的任务:
span$CHECK <- ave(dst(span$date), as.Date(span$date, tz = tz(span$date)), FUN = any)
我认为ave
对于这个函数来说是一个糟糕的名字,但是如果你能记住它存在,那么当你想要将摘要加入到它来自的data.frame时,它通常非常有用。
答案 2 :(得分:1)
按照@aosmith的建议,完成工作的最佳解决方案是。
limits = span %>% group_by(YEAR) %>% mutate(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS]),CHECK=FALSE)
limits$CHECK[(limits2$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE
使用ave功能是一个不错的选择,但我个人更喜欢坚持使用'dplyr'包。