使用日出和日落时间过滤时间序列数据

Filter Timeseries Data Using Sunrise and Sunset Times

我正在尝试对落在日落和日出之间的数据进行子集化。 数据:

library(tidyverse)
library(lubridate)
library(suncalc)

dat <- tibble(datetime = seq(as.POSIXct('2020-08-03 00:00:00'), 
                             as.POSIXct('2020-08-09 12:00:00'), 
                             by=3600),
              var1 = rnorm(157,2,1),
              var2 = rnorm(157,3,5)) %>% 
  mutate(getSunlightTimes(date = as.Date(datetime, format = '%m/%d/%Y'),
                         lat = 43.1, lon = -76.2, tz = 'America/New_York',
                         keep = c('sunrise', 'sunset'))) %>% 
  select(c(datetime, var1, var2, sunrise, sunset)) 

然后我想对数据进行子集化,这样我就只保留 datetime 在给定日期的日出和日落之间的行。我试过了:

myrange <- as.interval(unique(dat$sunrise), unique(dat$sunset))

dat <- dat %>% 
  filter(datetime %within% myrange)

这可以编译但会抛出警告并且不包含它应该包含的所有数据行。提前致谢。

试试这个:

首先,创建部分 dat。我将添加 date,因为我们需要它来进行计算和重新加入数据。

set.seed(42)
dat <- tibble(datetime = seq(as.POSIXct('2020-08-03 00:00:00'), 
                             as.POSIXct('2020-08-09 12:00:00'), 
                             by=3600),
              var1 = rnorm(157,2,1),
              var2 = rnorm(157,3,5)) %>%
  mutate(date = as.Date(datetime))
dat
# # A tibble: 157 x 4
#    datetime             var1   var2 date      
#    <dttm>              <dbl>  <dbl> <date>    
#  1 2020-08-03 00:00:00  3.37 -1.00  2020-08-03
#  2 2020-08-03 01:00:00  1.44  0.333 2020-08-03
#  3 2020-08-03 02:00:00  2.36  9.44  2020-08-03
#  4 2020-08-03 03:00:00  2.63  2.12  2020-08-03
#  5 2020-08-03 04:00:00  2.40 -2.36  2020-08-03
#  6 2020-08-03 05:00:00  1.89  3.82  2020-08-03
#  7 2020-08-03 06:00:00  3.51  1.19  2020-08-03
#  8 2020-08-03 07:00:00  1.91  5.95  2020-08-03
#  9 2020-08-03 08:00:00  4.02 10.2   2020-08-03
# 10 2020-08-03 09:00:00  1.94 -1.96  2020-08-03
# # ... with 147 more rows

现在将其减少到找到的不同 dates,获取这些日期的 sunrise/sunset,然后加入原始 dat(使用 left_join) .之后,我们可以 filter 我们需要的时间。

distinct(dat, date) %>%
  with(., getSunlightTimes(date = date,
                           lat = 43.1, lon = -76.2, tz = 'America/New_York',
                           keep = c('sunrise', 'sunset'))) %>% 
  left_join(dat, ., by = "date") %>%
  filter(sunrise <= datetime, datetime <= sunset)
# # A tibble: 85 x 8
#    datetime             var1  var2 date         lat   lon sunrise             sunset             
#    <dttm>              <dbl> <dbl> <date>     <dbl> <dbl> <dttm>              <dttm>             
#  1 2020-08-03 06:00:00 3.51   1.19 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  2 2020-08-03 07:00:00 1.91   5.95 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  3 2020-08-03 08:00:00 4.02  10.2  2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  4 2020-08-03 09:00:00 1.94  -1.96 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  5 2020-08-03 10:00:00 3.30   5.27 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  6 2020-08-03 11:00:00 4.29   3.42 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  7 2020-08-03 12:00:00 0.611  7.48 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  8 2020-08-03 13:00:00 1.72   1.85 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
#  9 2020-08-03 14:00:00 1.87   7.18 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
# 10 2020-08-03 15:00:00 2.64  -5.73 2020-08-03  43.1 -76.2 2020-08-03 05:59:13 2020-08-03 20:25:11
# # ... with 75 more rows

请注意,我们不能在此处使用 dplyr::between,因为该函数仅使用其第一个 leftright 参数。