Almacomet
Almacomet

Reputation: 211

Filter to Month-Day Interval

I have a data frame with daily observations across years. I would like to filter to a range, such as "March 10 to May 12" every year. Perhaps it's my poor googling skills, but I couldn't find some sort of month-day construction.

Here's a sample df:

set.seed(123)

dates <- seq.Date(from=as.Date("1970-01-01"), to=as.Date("2007-08-31"), by="days")

sample.df <- data.frame(date=dates, 
                        data=rnorm(length(dates)))

Another addition to complicate is to keep a range that crosses over years, such as "December 10 to February 2." It can be assumed all needed dates are contained within the dataframe, but might need to make some NA such as when the dataframe goes to 2007, so we cannot do December 10, 2007 to February 2, 2008.

Upvotes: 3

Views: 1769

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269431

This works for any number of years and for arbitrarily complex logical conditions. No packages are used.

monthday <- format(sample.df$date, "%m%d")

sample.df[ monthday >= "0310" & monthday <= "0512", ]   # mar 10 - may 12

sample.df[ monthday <= "0202" | monthday >= "1210", ]   # dec 10 - feb 02

sample.df[ monthday <= "0202" | 
           (monthday >= "0310" & monthday <= "0512") | 
           monthday >= "1210", ]   # both

Upvotes: 4

CPak
CPak

Reputation: 13581

You can use dplyr and lubridate:

library(dplyr)
library(lubridate)

sample.df %>% filter(between(date, ymd("2006-03-10"), ymd("2006-05-12")))

sample.df %>% filter(between(date, ymd("2006-10-11"), ymd("2007-02-01")))

Ignoring year:

sample.df %>% 
   mutate(dummy = (month(date)*100) + day(date)) %>% 
   filter(between(dummy,310,512)) %>% 
   select(-dummy)

Upvotes: 3

Related Questions