Home > Back-end >  How to filter dates with double curly brackets?
How to filter dates with double curly brackets?

Time:04-02

Similar to my other question about double curly brackets within ggplot, I'm also struggling with using double curly brackets with filtering dates generally. In this function, users can specify a time period (week, month) and then the function filters based on the respective time period. For instance, selecting 'month' should cause the function to focus just on the Month and Month_score columns. However, it keeps failing and providing incorrect output:

Here's my sample data along with 2 attempts that I made:

#Sample data

library(dplyr)
library(lubdridate)

test <- tibble(Week = seq(as.Date("2014-09-04"), by = "week", length.out = 8),
               Month = ymd(rep('2014-09-01', 4), rep('2014-10-01', 4)),
               Week_score = c(2, 3, 4, 6, 5, 7, 8, 9),
               Month_score = c(15, NA, NA, NA, 29, NA, NA, NA))

Attempt 1--no columns are removed (which is incorrect):

date_filter <- function(data, time_period = c("Week", "Month"), start_date = NA_Date_) {


  data %>%
    filter({{time_period}} > start_date)
}

date_filter(data = test, time_period = "Week", start_date = '2014-09-06')

Attempt 2: I explicitly callout that start_date is a date, but I get the below error

date_filter <- function(data, time_period = c("Week", "Month"), start_date = NA_Date_) {


  data %>%
    filter({{time_period}} > as.Date(start_date))
}

date_filter(data = test, time_period = "Week", start_date = '2014-09-06')

CodePudding user response:

{{}} is meant to be used on unquoted variable names, not on strings.

Remove the "" from time_period when calling your function, and it works:

date_filter <- function(data, time_period, start_date = NA_Date_) {
  
  
  data %>%
    filter({{time_period}} > as.Date(start_date))
}

date_filter(data = test, time_period = Week, start_date = '2014-09-06')

#> # A tibble: 7 × 4
#>   Week       Month      Week_score Month_score
#>   <date>     <date>          <dbl>       <dbl>
#> 1 2014-09-11 2014-09-01          3          NA
#> 2 2014-09-18 2014-09-01          4          NA
#> 3 2014-09-25 2014-09-01          6          NA
#> 4 2014-10-02 2014-10-01          5          29
#> 5 2014-10-09 2014-10-01          7          NA
#> 6 2014-10-16 2014-10-01          8          NA
#> 7 2014-10-23 2014-10-01          9          NA

Created on 2022-04-02 by the reprex package (v2.0.1)

rlang has a nice article which I recommend everybody to read before working with {{}}.

Why does time_period = "Week" work in the first function but not in the other?

Because {{time_period}} gets interpreted as a string, and not the variable Week. You quite literally are trying to compare "Week" > "2014-09-06" in the first function (which is always TRUE), and "Week" > as.Date("2014-09-06") in the second function (which makes R want to convert "Week" into a date, and thus you get an error).

CodePudding user response:

If we want to pass either quoted or unquoted, then convert to sym with ensym

date_filter <- function(data, time_period = c("Week", "Month"), 
      start_date = NA_Date_) {

  time_period <- rlang::ensym(time_period)
  data %>%
    filter(!!time_period > start_date)
}

-testing

> date_filter(data = test, time_period = "Week", start_date = '2014-09-06')
# A tibble: 7 × 4
  Week       Month      Week_score Month_score
  <date>     <date>          <dbl>       <dbl>
1 2014-09-11 2014-09-01          3          NA
2 2014-09-18 2014-09-01          4          NA
3 2014-09-25 2014-09-01          6          NA
4 2014-10-02 2014-10-01          5          29
5 2014-10-09 2014-10-01          7          NA
6 2014-10-16 2014-10-01          8          NA
7 2014-10-23 2014-10-01          9          NA
> 
> date_filter(data = test, time_period = Week, start_date = '2014-09-06')
# A tibble: 7 × 4
  Week       Month      Week_score Month_score
  <date>     <date>          <dbl>       <dbl>
1 2014-09-11 2014-09-01          3          NA
2 2014-09-18 2014-09-01          4          NA
3 2014-09-25 2014-09-01          6          NA
4 2014-10-02 2014-10-01          5          29
5 2014-10-09 2014-10-01          7          NA
6 2014-10-16 2014-10-01          8          NA
7 2014-10-23 2014-10-01          9          NA
  • Related