Search code examples
rvariablesdplyrfiltertidyverse

Use a variable name as function argument


I would like to write a unique function to (among other things) filter a database for different variables at different threshold. I found a way to indicate the variable I want to filter on in the function itself, but not sure is the best way.

How should I go about it?

example_db <- data.frame(name=c("A","B","C"), 
                         value_1=c(1,2,3), 
                         value_2=c(2,3,1))

advanced_filter <- function(data,variable,limit){
  
  require(dplyr)
  data <- data %>% 
    dplyr::filter(variabe>limit) 
  
  return(data)
}

Expected result:

advanced_filter(example_db,value_1,2)

name value_1 value_2
1    C       3       1

My attempt:

advance_filter <- function(data,variable,limit){
  require(dplyr)
  f <- paste(variable, ">",  limit)
  data <- data %>% 
    dplyr::filter_(f) 
  
  return(data)
}


advance_filter(example_db,"value_1",2)

Solution

  • Allan Cameron's answer is obviously correct and only requires base R, just for posterity's sake, here's the tidy version.

    example_db <- data.frame(name=c("A","B","C"), 
                             value_1=c(1,2,3), 
                             value_2=c(2,3,1))
    
    
    
    advanced_filter <- function(data,variable,limit){
      require(dplyr)
      vbl <- enquo(variable)
      data %>% 
        dplyr::filter(!!vbl > limit) 
    }
    
    advanced_filter(example_db,value_1,2)
    #> Loading required package: dplyr
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    #>   name value_1 value_2
    #> 1    C       3       1
    

    Created on 2022-01-28 by the reprex package (v2.0.1)

    Or, following @TimTeaFan's comment below:

    example_db <- data.frame(name=c("A","B","C"), 
                             value_1=c(1,2,3), 
                             value_2=c(2,3,1))
    
    
    
    advanced_filter <- function(data,variable,limit){
      require(dplyr)
      data %>% 
        dplyr::filter({{variable}} > limit) 
    }
    
    advanced_filter(example_db,value_1,2)
    #> Loading required package: dplyr
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    #>   name value_1 value_2
    #> 1    C       3       1
    

    Created on 2022-01-28 by the reprex package (v2.0.1)