Why doesn't dplyr filter() work within function (i.e. using variable for column name)?

Viewed 5983

A function for filtering, grouping and mutating data with dplyr functions. Basic pipe sequence works great outside a function, that is where I use the true column names. Put it in a function where the column name is a variable and some of the functions work but some don't most notably dplyr::filter(). For example:

var1 <- c('yes', NA, NA, 'yes', 'yes', NA, NA, NA, 'yes', NA, 'no', 'no', 'no', 'maybe', NA, 'maybe', 'maybe', 'maybe')

var2 <- c(1:18)

df <- data.frame(var1, var2)

This works fine (i.e. filters NA's):

df%>%filter(!is.na(var1))

...but this doesn't:

x <- "var1"

df%>%filter(!is.na(x))

...but this does:

df%>%select(x)

It's NA's that need to be filtered out specifically.

Tried get("x"), no good, and slicing:

df[!is.na(x),]

...no good, either.

Any ideas on how to pass a variable to filter inside (or outside) a function and why a variable is working with other dplyr functions?

5 Answers

Using !!rlang::parse_quo() you can filter using a character variable.

See two reproducible examples below:

# Create DF
df <- data.frame(
  var1 = c("yes", NA, NA, "yes", "yes", NA, NA, NA, "yes", NA, "no", "no", "no", "maybe", NA, "maybe", "maybe", "maybe"),
  var2 = c(1:18)
)

Using x to define a variable

x <- "var1"
FILTER <- paste0("!is.na(", x, ")")
df |> dplyr::filter(!!rlang::parse_quo(FILTER, env = parent.frame()))
#>     var1 var2
#> 1    yes    1
#> 2    yes    4
#> 3    yes    5
#> 4    yes    9
#> 5     no   11
#> 6     no   12
#> 7     no   13
#> 8  maybe   14
#> 9  maybe   16
#> 10 maybe   17
#> 11 maybe   18

Using FILTER to create a full filter statement

FILTER <- "!is.na(var1)"
df |> dplyr::filter(!!rlang::parse_quo(FILTER, env = parent.frame()))
#>     var1 var2
#> 1    yes    1
#> 2    yes    4
#> 3    yes    5
#> 4    yes    9
#> 5     no   11
#> 6     no   12
#> 7     no   13
#> 8  maybe   14
#> 9  maybe   16
#> 10 maybe   17
#> 11 maybe   18

Created on 2022-09-14 by the reprex package (v2.0.1)

Related