Function

Fundamentals

Function Components

R functions are objects in their own right or “first-class functions”.

f02 <- function(x, y) {
  # A comment
  x + y
}

typeof(f02)
#> [1] "closure"
class(f02)
#> [1] "function"
sloop::ftype(f02)
#> [1] "function"
sloop::otype(f02)
#> [1] "base"

3 Function components

formals(f02)
#> $x
#> 
#> 
#> $y
body(f02)
#> {
#>     x + y
#> }
environment(f02)
#> <environment: R_GlobalEnv>

srcref attribute is used for printing the source code.

attributes(f02)
#> $srcref
#> function(x, y) {
#>   # A comment
#>   x + y
#> }
print.function(f02)
#> function(x, y) {
#>   # A comment
#>   x + y
#> }

First-class Function

anonymous function (no name binding is necessary)

lapply(mtcars, function(x) length(unique(x)))
Filter(function(x) !is.numeric(x), mtcars)
integrate(function(x) sin(x) ^ 2, 0, pi)

List of functions

funs <- list(
  half = function(x) x / 2,
  double = function(x) x * 2
)

funs$double(10)
#> [1] 20

do.call()

args <- list(1:10, na.rm = TRUE)
do.call(mean, args)
#> [1] 5.5

Exercise

  1. match.fun() finds the function
match.fun("mean")
#> function (x, ...) 
#> UseMethod("mean")
#> <bytecode: 0x7f7c4028a358>
#> <environment: namespace:base>
  1. Calling anonymous function
class(function(x) x + 1)
#> [1] "function"
(function(x) x + 1)(2)
#> [1] 3
  1. List all function in base
objs <- mget(ls("package:base", all = TRUE), inherits = TRUE)
funs <- Filter(is.function, objs)

Find functions that has most arguments

library(purrr)
library(dplyr)
library(tibble)

Helper to counts number of arguments

get_num_args <- function(f){
  
  args <- formals(f)
  if(is.null(args)) return(NA_integer_) # for primitive function
  length(args)
  
}

get_num_args(f02)
#> [1] 2
get_num_args(sum)
#> [1] NA
basefuns_tbl <- map_dbl(funs, get_num_args) %>% 
  enframe("base_fun", "num_args")

Base functions that has most arguments

basefuns_tbl %>% 
  arrange(desc(num_args)) %>% 
  head()
#> # A tibble: 6 × 2
#>   base_fun         num_args
#>   <chr>               <dbl>
#> 1 scan                   22
#> 2 format.default         16
#> 3 source                 16
#> 4 formatC                15
#> 5 library                13
#> 6 merge.data.frame       13