Search code examples
rtidyrtidyversetidyeval

Excluding rather than including gather variable using tidyeval tidyr


If I wanted to exclude some columns (Ozone, Day, Month) that get "gathered" I can do this:

tidyr::gather(airquality, key, value, -Ozone, -Day, -Month)

But in a function, it isn't clear to me how to do this. This seems clumsy though it works:

my_gather <- function(col_to_compare) {
  gather_cols = dplyr::setdiff(c("Ozone", "Solar.R","Wind","Temp"), col_to_compare)
  tidyr::gather(airquality, key, value, !! rlang::enquo(gather_cols))
}

my_gather("Ozone")

Any idea how to exclude columns in a more rigorous way?

Note: This is with tidyr 0.7.0


Solution

  • Since gather() has the same semantics as select(), this question is a duplicate of Remove columns the tidyeval way.

    You can use -one_of(vars) which is the recommended way to do it.

    Alternatively you can construct a list of negated symbols and splice these expressions within the gather() call. Here is how to create symbols and wrap them in calls to -:

    # This creates a list of symbols
    syms <- syms(vars)
    
    # This creates a list of calls:
    exprs <- map(syms, function(sym) lang("-", sym))
    

    You can then splice the list of calls with !!!:

    df %>% gather(key, value, !!! exprs)