3

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

boshek
  • 4,100
  • 1
  • 31
  • 55
  • Do you want a function that uses column names as strings? If so, you might find `-one_of(cols_to_compare)` useful. – aosmith Aug 17 '17 at 20:55
  • Do you want to pass the columns as something like `my_gather(Ozone)` rather than `my_gather(-Ozone)`? I think the latter is reasonably straightforward, the first one would be slightly more tricky. – Nick Nimchuk Aug 17 '17 at 21:32
  • aosmith is right that `one_of()` is the solution here. – Lionel Henry Aug 18 '17 at 06:21
  • Also you shouldn't use `enquo()` in this way (it shouldn't even work in that context, I think that's a bug). `enquo()` is for capturing an argument supplied by the user and wrap the captured expression in a quosure. Here there is no need to capture and it doesn't help to use a quosure. – Lionel Henry Aug 18 '17 at 12:22

1 Answers1

3

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)
Lionel Henry
  • 6,652
  • 27
  • 33