Subset a dataframe between 2 dates

I am working with daily returns from a Brazilian Index (IBOV) since 1993, I am trying to figure out the best way to subset for periods between 2 dates.

The data frame (IBOV_RET) is as follows :

head(IBOV_RET)
        DATE    1D_RETURN
1 1993-04-28 -0.008163265
2 1993-04-29 -0.024691358
3 1993-04-30  0.016877637
4 1993-05-03  0.000000000
5 1993-05-04  0.033195021
6 1993-05-05 -0.012048193
...

I set 2 variables DATE1 and DATE2 as dates

DATE1 <- as.Date("2014-04-01")
DATE2 <- as.Date("2014-05-05")

I was able to create a new subset using this code:

TEST <- IBOV_RET[IBOV_RET$DATE >= DATE1 & IBOV_RET$DATE <= DATE2,]

It worked, but I was wondering if there is a better way to subset the data between 2 date, maybe using subset.


As already pointed out by @MrFlick, you dont get around the basic logic of subsetting. One way to make it easier for you to subset your specific data.frame would be to define a function that takes two inputs like DATE1 and DATE2 in your example and then returns the subset of IBOV_RET according to those subset parameters.

myfunc <- function(x,y){IBOV_RET[IBOV_RET$DATE >= x & IBOV_RET$DATE <= y,]}

DATE1 <- as.Date("1993-04-29")
DATE2 <- as.Date("1993-05-04")

Test <- myfunc(DATE1,DATE2)    

#> Test
#        DATE  X1D_RETURN
#2 1993-04-29 -0.02469136
#3 1993-04-30  0.01687764
#4 1993-05-03  0.00000000
#5 1993-05-04  0.03319502

You can also enter the specific dates directly into myfunc:

myfunc(as.Date("1993-04-29"),as.Date("1993-05-04")) #will produce the same result

You can use the subset() function with the & operator:

subset(IBOV_RET, DATE1> XXXX-XX-XX & DATE2 < XXXX-XX-XX)

Updating for a more "tidyverse-oriented" approach:

IBOV_RET %>%
  filter(DATE1 > XXXX-XX-XX, DATE2 < XXXX-XX-XX) #comma same as &

There is no real other way to extract date ranges. The logic is the same as extracting a range of numeric values as well, you just need to do the explicit Date conversion as you've done. You can make your subsetting shorter as you would with any other subsetting task with subset or with. You can break ranges into intervals with cut (there is a specific cut.Date overload). But base R does not have any way to specify Date literals so you cannot avoid the conversion. I can't imagine what other sort of syntax you may have had in mind.


I believe lubridate could help here;

daterange <- interval(DATE1, DATE2)
TEST <- IBOV_RET[which(Date %within% daterange),]

What about:

DATE1 <- as.Date("1993-04-29")
DATE2 <- as.Date("1993-05-04")

# creating a data range with the start and end date:
dates <- seq(DATE1, DATE2, by="days")

IBOV_RET <- subset(IBOV_RET, DATE %in% dates)