musialmi
musialmi

Reputation: 150

How to pass a column name as an argument of a function which uses dplyr, without passing it as a string?

Here: https://rpubs.com/hadley/dplyr-programming they write the following.

my_summarise <- function(df, group_by) {
  group_by <- enquo(group_by)
  print(group_by)

  df %>%
    group_by(!!group_by) %>%
    summarise(a = mean(a))
}

my_summarise(df, g1)
#> ~g1
#> # A tibble: 2 × 2
#>      g1     a
#>   <dbl> <dbl>
#> 1     1   4.5
#> 2     2   2.0

So I try to copy it, using my idea of a function and my data.

library(MASS)
not.fun <- function(data, column) {
  column <- enquo(column)
  data %>% slice(1:10) %>% select(!!column)
}

not.fun(MASS::Cars93, Length)
Error in select(., !!column) : unused argument (!!column) 

But, guess what, it doesn't work. How to make it work, without using strings? I would be interested in a result possibly done in base R if it'd take as many lines of code to write as a result in some specific package.

Upvotes: 0

Views: 76

Answers (2)

akrun
akrun

Reputation: 887118

It is likely to be an issue of function masking as @MrFlick described in his post. If that issue is resolved, instead of the enquo/!! the curly-curly operator can be used {{..}} as well

not.fun <- function(data, column) { 
                    data %>%
                         slice(1:10) %>%
                         dplyr::select({{column}})
   }


not.fun(MASS::Cars93, Length)
#   Length
#1     177
#2     195
#3     180
#4     193
#5     186
#6     189
#7     200
#8     216
#9     198
#10    206

Upvotes: 1

MrFlick
MrFlick

Reputation: 206232

The MASS package has it's own select() function. If you load MASS after you load dplyr, you mask the dplyr version of the function. You could be expliclt about which select function you want:

library(MASS)
not.fun <- function(data, column) {
  column <- enquo(column)
  data %>% slice(1:10) %>% dplyr::select(!!column)
}

not.fun(MASS::Cars93, Length)

Upvotes: 2

Related Questions