Using the name of a data frame column as a parameter value for a function which filters that column in the data frame

Viewed 148

I would like to write a function which uses dplyr::filter() within the function. When writing the function I ran into an issue with using a parameter name in the function that is also a name of one of the columns of the data frame I am filtering.

Suppose I call the data frame to be filtered dat:

library(dplyr)
dat <- data.frame(
a = c(1:10),
b = c(2,2,2,2,2,3,1,1,4,4)
)

and name the function test.filter(),

test.filter <- function(b, test.data = dat){
dat.t <- filter(test.data,
              b == b)
return(dat.t)
}

Here I am passing a value b to the function and asking it to filter the column b based on the value b. I believe the function

test.filter(b = 4,
        test.data = dat)

should produce the same result as

filter(dat,
   b == 4)

However this is not the case. I am wondering if there is something I am not considering in terms of the scope of a function. Any help is appreciated!

3 Answers

It is a case where the argument 'b' of the function is the same as the column name. One option is to do !! inside the function argument

test.filter <- function(b, test.data = dat){
   filter(test.data,
           b == !!b)

   }

test.filter(b = 4,
     test.data = dat)

If the argument passed to the function is similar to one of the column name in the dataframe, we can use the curly-curly ({{ }}) operator from rlang to evaluate column name

library(rlang)

test.filter <- function(b, test.data = dat) {
      dplyr::filter(dat,{{b}} == b)
}

test.filter(b = 4,test.data = dat)
#   a b
#1  9 4
#2 10 4


test.filter(b = 2,test.data = dat)
#  a b
#1 1 2
#2 2 2
#3 3 2
#4 4 2
#5 5 2

Thanks for the helpful answers. A friend let me know that the underlying reason for the issue is dplyr uses lazy eval, so b==b evaluates to all true.

Related