使用汇总(dplyr)的结果来改变原始数据帧

Fab*_*bio 3 r posixct lubridate dplyr

我有一个相当大的数据框,其中包含一列POSIXct日期时间(每小时数据约为10年).我会在夏令时期间标记当天所有的行.例如,如果夏令时开始于'2000-04-02 03:00:00'(DOY = 93),我希望可以标记前两个小时的DOY = 93.虽然我dplyr的新手我会尽可能多地使用这个包,并避免for循环尽可能

例如:

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)
Run Code Online (Sandbox Code Playgroud)

要查找应用夏令时的一年中的不同日期,请使用dplyr

library(dplyr)
limits = span %.% group_by(YEAR) %.% summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS]))
Run Code Online (Sandbox Code Playgroud)

这给了

      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
Run Code Online (Sandbox Code Playgroud)

现在,我将在跨度数据帧中"管道"上述结果,而不使用低效的for循环.

解决方案1

在@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      
Run Code Online (Sandbox Code Playgroud)

解决方案2

在@beetroot和@matthew-plourde的帮助下,问题已经解决:缺少内部联接:

limits = span %>% group_by(YEAR) %>% summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS])) %>% inner_join(span, by='YEAR')
Run Code Online (Sandbox Code Playgroud)

然后我添加了一个新列(CHECK)来填充Daylight-savings日的正确值

limits$CHECK = FALSE
limits$CHECK[(limits$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE
Run Code Online (Sandbox Code Playgroud)

Mat*_*rde 9

正如@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
Run Code Online (Sandbox Code Playgroud)