这个问题在这里已有答案:
我们假设我有三年的时间序列,如下所示:
library(lubridate)
ts1 <- seq(ymd('2016-01-01'), ymd('2018-12-31'), '1 day')
现在我想指出一年中的一些时间,例如北半球的天文夏季,从6月21日开始到9月23日结束,并检查我的ts1
矢量的哪些元素落入这个范围。我怎么能这样做,最好是使用润滑剂,但不是必须的?
我会创建一个新的日期变量,将所有日期放在同一年,然后检查:
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
qazxsw poi将把所有日期都放到2000年(这是一个随意的选择)。
这是一个ymd(format(odate, "2000-%m-%d"))
方法。首先,我们需要获得我们这一时期的一年中的一天价值。北半球(6月21日)的天文夏季开始时间为第172天,结束时间为第267天(9月23日)。你可以用case_when
做到这一点。
然后我们需要为我们的数据帧做同样的事情。所以我们得到了你的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
包即可完成此操作 -
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)]
创建一个字符向量,其元素的格式为mmdd。然后> 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
是一个逻辑向量,表明ts1的哪些元素在期望的范围内,最后一行子集ok
到这些范围:
ts1