如何检查日期是否在一年的指定时间内

时间:2019-04-12 11:15:06

标签: r date lubridate base

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

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

现在我想指定一年中的某个时间,例如北半球的天文夏季,该天从6月21日开始,到9月23日结束,并检查ts1向量中的哪些元素落入该范围。我该怎么做,充其量是最好的,但不是必须的?

4 个答案:

答案 0 :(得分:2)

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

<xsl:for-each select="tags/tag[contains(display,'Yes')]">

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 将所有日期设为2000年(这是任意选择)。

答案 1 :(得分:1)

这是一种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

答案 2 :(得分:0)

您只需使用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

答案 3 :(得分:0)

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

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