Search code examples
rfunctiondplyrnse

Custom functions: How to refer to another column using sym() and !! (bang bang) without using funs() in dplyr 0.8.0?


In dplyr 0.8.0, the wrapper funs() (used within mutate_at() or summarise_at()) is soft-deprecated.

The new recommended syntax is to use ~sum(.) instead of funs(sum(.)), which is the "old style" I would have previously used. My aim is to translate the old syntax to the new syntax , however I have been experiencing issues when the function call within funs() uses (!!sym()) to convert a character input for a column name to a symbol that can be recognised within the function.

Here's a made-up example of how I would write a function in the old dplyr style.

var is a character string that refers to the column name, and at funs() it is multiplied by Sepal.Length.

multiply_by <- function(var){
  iris %>%
    mutate_at("Sepal.Length",funs(.*!!sym(var)))
}
multiply_by("Sepal.Width") # This works

My question is that I cannot figure out how to translate this to the new ~ syntax without encountering an error. If I run the following it triggers an 'invalid argument type' error:

multiply_by2 <- function(var){
  iris %>%
    mutate_at("Sepal.Length",~.*!!sym(var))
}
multiply_by2("Sepal.Width")
# Error in !sym(var) : invalid argument type 

Can someone help? At the moment I can get by with using funs(), but since it is being soft-deprecated I would like to migrate my code to a stable format if/when it becomes fully hard-deprecated. Thank you!


Solution

  • One option as mentioned in the issues would be to use .data

    multiply_by2 <- function(var){
     iris %>% 
           mutate_at("Sepal.Length", list( ~ .* .data[[var]]))
    
    }
    
    multiply_by2("Sepal.Width")