【问题标题】:How to check if date is within specified time of the year [duplicate]如何检查日期是否在一年中的指定时间内[重复]
【发布时间】:2019-04-12 11:15:05
【问题描述】:

假设我有一个三年的时间序列,如下所示:

library(lubridate)
ts1 <- seq(ymd('2016-01-01'), ymd('2018-12-31'), '1 day')

现在我想指定一年中的某个时间,例如北半球的天文夏季,从 6 月 21 日开始,到 9 月 23 日结束,然后检查我的 ts1 向量的哪些元素属于这个范围。我怎样才能做到这一点,最好使用 lubridate,但不是必须的?

【问题讨论】:

  • 如果你在一个向量中定义了日期,然后在那个列表中搜索,会不会不起作用:示例:timerange &lt;- seq(ymd('2016-06-21'), ymd('2016-09-23'), '1 day') 并过滤ts1[ts1 %in% timerange]
  • 但这只会出现在第一年的夏天,而不是所有的三年。
  • 是的,我们的想法是构建一个向量并将其用于过滤。您还可以使用monthdateweek 等函数运行过滤器

标签: r date lubridate base


【解决方案1】:

我会创建一个新的日期变量,将所有日期放在同一年,然后检查:

library(lubridate)
library(dplyr)
ts1 <- seq(ymd('2016-01-01'), ymd('2018-12-31'), '1 day')
df <- data_frame(odate = ts1)
df %>% mutate(temp_date = ymd(format(odate, "2000-%m-%d"))) %>%
    mutate(in_summer = temp_date %in% 
                        seq(ymd('2000-06-21'), ymd('2000-09-23'), '1 day')) %>%
    select(-temp_date)
## # A tibble: 1,096 x 2
##    odate      in_summer
##    <date>     <lgl>    
##  1 2016-01-01 FALSE    
##  2 2016-01-02 FALSE    
##  3 2016-01-03 FALSE    
##  4 2016-01-04 FALSE    
##  5 2016-01-05 FALSE    
##  6 2016-01-06 FALSE    
##  7 2016-01-07 FALSE    
##  8 2016-01-08 FALSE    
##  9 2016-01-09 FALSE    
## 10 2016-01-10 FALSE    
## # ... with 1,086 more rows

ymd(format(odate, "2000-%m-%d")) 会将所有日期放入 2000 年(这是任意选择)。

【讨论】:

  • 您可以使用 yday() 函数返回年份而不是将所有日期放入 2000 年
  • 我以为一定有这样的功能。很高兴知道。谢谢!
  • 我担心yday 会让闰年搞砸。例如,2000 年的 3 月 1 日是一年中的第 61 天,但在 1999 年是第 60 天。
  • @jakes 听起来不错。
【解决方案2】:

这是case_when 方法。首先,我们需要为我们的时期获取一年中的某一天值。北半球天文夏季的开始(6 月 21 日)是第 172天,结束是第 267天(9 月 23 日)。你可以用lubridate::yday("2019-06-21")来做。

然后我们需要对我们的数据框做同样的事情。所以我们得到了你的ts1。我们需要将其转换为data.frametibble 并计算yday

library(lubridate)
library(dplyr)

ts1 <- seq(ymd('2016-01-01'), ymd('2018-12-31'), '1 day')

ts1 <- tibble(date = (ts1),
              day = yday(ts1))

使用sqldf

library(sqldf)

sqldf("select ts1.*, case when (ts1.day >= 172 and ts1.day <= 267)
      then 1 else 0 end as TOY
      from ts1", method = c("Date", "numeric", "logical")) %>%
  as_tibble()

# A tibble: 1,096 x 3
   date         day TOY  
   <date>     <dbl> <lgl>
 1 2016-01-01     1 FALSE
 2 2016-01-02     2 FALSE
 3 2016-01-03     3 FALSE
 4 2016-01-04     4 FALSE
 5 2016-01-05     5 FALSE
 6 2016-01-06     6 FALSE
 7 2016-01-07     7 FALSE
 8 2016-01-08     8 FALSE
 9 2016-01-09     9 FALSE
10 2016-01-10    10 FALSE
# ... with 1,086 more rows

使用dplyr

ts1 %>%
  mutate(TOY = case_when(day >= 172 & day <= 267 ~ "summer",
                         TRUE ~ "other"))

# A tibble: 1,096 x 3
   date         day TOY  
   <date>     <dbl> <chr>
 1 2016-01-01     1 other
 2 2016-01-02     2 other
 3 2016-01-03     3 other
 4 2016-01-04     4 other
 5 2016-01-05     5 other
 6 2016-01-06     6 other
 7 2016-01-07     7 other
 8 2016-01-08     8 other
 9 2016-01-09     9 other
10 2016-01-10    10 other
# ... with 1,086 more rows

【讨论】:

    【解决方案3】:

    您可以通过使用data.table 包简单地做到这一点-

    > library(data.table)
    > library(lubridate)
    > ts1 <- data.frame(date=seq(ymd('2016-01-01'), ymd('2018-12-31'), '1 day'))
    > search_dt <- seq(as.Date("2000-06-21"), as.Date("2000-09-23"), by="days")
    > setDT(ts1)[, ind:= ifelse(date %in% search_dt,TRUE,FALSE)]
    

    输出-

    > ts1
                date   ind
       1: 2016-01-01 FALSE
       2: 2016-01-02 FALSE
       3: 2016-01-03 FALSE
       4: 2016-01-04 FALSE
       5: 2016-01-05 FALSE
      ---                 
    1092: 2018-12-27 FALSE
    1093: 2018-12-28 FALSE
    1094: 2018-12-29 FALSE
    1095: 2018-12-30 FALSE
    1096: 2018-12-31 FALSE
    

    【讨论】:

      【解决方案4】:

      创建一个字符向量,其元素的格式为 mmdd。然后ok 是一个逻辑向量,指示 ts1 的哪些元素在所需范围内,最后一行子集 ts1 到这些范围:

      mmdd <- format(ts1, "%m%d") 
      ok <- mmdd >= "0621" & mmdd <= "0923"
      ts1[ok]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多