Joanna OK
Joanna OK

Reputation: 103

Select the same period every year in R

This seems really simple, yet I can't find an easy solution. I'm working with future streamflow projections for every day of a 25 year period (2024-2050). I'm only interested in streamflow during the 61 day period between 11th of April and 10th of June each year. I want to extract the data from the seq and Data column that are within this period for each year and have it in a data frame together.

Example data:

library(xts)
seq <- timeBasedSeq('2024-01-01/2050-12-31') 
Data <- xts(1:length(seq),seq) 

I want to achieve something like this BUT with all the dates between April 11 and June 10th and for all years (2024-2050). This is a shortened sample output:

seq_x <- c("2024-04-11","2024-06-10","2025-04-11","2025-06-10","2026-04-11","2027-06-10", 
           "2027-04-11", "2027-06-10")
Data_x  <- c(102, 162, 467, 527, 832, 892, 1197, 1257)
output <- data.frame(seq_x, Data_x)

This question is similar to: Calculating average for certain time period in every year and select date ranges for multiple years in r but doesn't provide an efficient answer to my question on how to extract the same period over multiple years.

Upvotes: 1

Views: 429

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 389105

Here is a base R approach :

dates <- index(Data)
month <- as.integer(format(dates, '%m'))
day <- as.integer(format(dates, '%d'))
result <- Data[month == 4 & day >= 11 | month == 5 | month == 6 & day <= 10]
result

#2024-04-11  102
#2024-04-12  103
#2024-04-13  104
#2024-04-14  105
#2024-04-15  106
#2024-04-16  107
#...
#...
#2024-06-07  159
#2024-06-08  160
#2024-06-09  161
#2024-06-10  162
#2025-04-11  467
#2025-04-12  468
#...
#...

Upvotes: 2

G. Grothendieck
G. Grothendieck

Reputation: 269854

Create an mmdd character string and subset using it:

mmdd <- format(time(Data), "%m%d")
Data1 <- Data[mmdd >= "0411" & mmdd <= "0610"]

These would also work. They shift the dates back by 10 days in which case it coincides with April and May

Data2 <- Data[format(time(Data)-10, "%m") %in% c("04", "05")]

or

Data3 <- Data[ cycle(as.yearmon(time(Data)-10)) %in% 4:5 ]

The command fortify.zoo(x) can be used to convert an xts object x to a data frame.

Upvotes: 2

akrun
akrun

Reputation: 887471

Here is an option. Do a group by year of the 'seq_x', then summarise to create a list column by subsetting 'Data' based on the first and last elements of 'seq_x' and select the column

library(dplyr)
library(lubridate)
library(tidyr)
library(purrr)
output %>%
     group_by(year = year(seq_x)) %>%
     summarise(new = list(Data[str_c(first(seq_x), last(seq_x), sep="::")]),
         .groups = 'drop') %>%          
      pull(new) %>% 
      invoke(rbind, .)
#           [,1]
#2024-04-11  102
#2024-04-12  103
#2024-04-13  104
#2024-04-14  105
#2024-04-15  106
#2024-04-16  107
# ...

Upvotes: 0

Related Questions