ranonymous-functiontilde

With which generality can tilde operator be used to build anonymous functions?


Inside some functions as dplyr::mutate_at or purrr::map, it seems that one can use tilde operator ~ to build anonymous functions.

For example, one can do as in the linked question: map(iris, ~length(unique(.)))

Or also: mtcars %>% mutate_all(~.*2)

I tried to imitate this inside sapply, to avoid sapply(list, function(item) {something_with_item}). I was writing sapply(list, ~ something_with_.) but I get an error

Error in match.fun(FUN) : 
  '~ something_with_.' is not a function, character or symbol

A reproducible example:

> sapply(names(mtcars),function(item) mean(mtcars[[item]]))
       mpg        cyl       disp         hp       drat         wt       qsec 
 20.090625   6.187500 230.721875 146.687500   3.596563   3.217250  17.848750 
        vs         am       gear       carb 
  0.437500   0.406250   3.687500   2.812500 
> sapply(names(mtcars),~mean(mtcars[[.]]))
Error in match.fun(FUN) : 
  '~mean(mtcars[[.]])' is not a function, character or symbol

Why? Understanding this syntaxis as a function is just a behaviour of some packages as dplyr and purrr? Is it understood by base R for some special cases?

Thank you!


Solution

  • As caldwellst says above, the tilda ~ is used to create a formula object, which is a bit of unevaluated code that can be used later. Formulae are not the same as functions, and the purrr functions work with formulae because they make a call to rlang::as_function (via purrr::as_mapper) in the background. The *apply functions obviously don't do this, though you can imitate this behavior by calling one of the above functions in your own modified *apply function (it's better to just use the map functions, the following is just to illustrate the point):

    # Write function with `as_mapper()`.
    fapply <- function(x, func) {
        sapply(x, purrr::as_mapper(func))
    }
    
    # Now we can use formulae.
    fapply(names(mtcars), ~ mean(mtcars[[.]]))
    
    #### OUTPUT ####
    
           mpg        cyl       disp         hp       drat         wt       qsec         vs         am       gear       carb 
     20.090625   6.187500 230.721875 146.687500   3.596563   3.217250  17.848750   0.437500   0.406250   3.687500   2.812500