假设我有一个三年时间序列,如下所示:
library(lubridate)
ts1 <- seq(ymd('2016-01-01'), ymd('2018-12-31'), '1 day')
现在我想指定一年中的某个时间,例如北半球的天文夏季,该天从6月21日开始,到9月23日结束,并检查ts1
向量中的哪些元素落入该范围。我该怎么做,充其量是最好的,但不是必须的?
答案 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.frame
或tibble
并计算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]