Press "Enter" to skip to content

What are Function arguments in R?

Zigya Acadmey 0

Arguments are always named when we define any function. When the function is called you do not have to specify the name of the argument. Arguments are optional; you do not have to specify a value for them. They can have a default value, which is used if you do not specify a value for that argument yourself. You can use as many arguments as you like, there is no limit to the number of arguments. An argument list comprises of comma-separated values that contain the various formal arguments.

Arguments

It’s useful to distinguish between the formal arguments and the actual arguments of a function. The formal arguments are a property of the function, whereas the actual or calling arguments can vary each time you call the function. This section discusses how calling arguments are mapped to formal arguments, how you can call a function given a list of arguments, how default arguments work, and the impact of lazy evaluation.

Calling functions

When calling a function you can specify arguments by position, by complete name, or by partial name.

> fun <- function(abcdef, bcde1, bcde2) {
+ list(a = abcdef, b1 = bcde1, b2 = bcde2)
+ }
> str(f(1, 2, 3))
 List of 3
  $ a : num 1
  $ b1: num 2
  $ b2: num 3
> str(f(2, 3, abcdef = 1))
 List of 3
  $ a : num 1
  $ b1: num 2
  $ b2: num 3
 
# Can abbreviate long argument names:
> str(f(2, 3, a = 1))
 List of 3
  $ a : num 1
  $ b1: num 2
  $ b2: num 3
 
# But this doesn't work because abbreviation is ambiguous
> str(f(1, 3, b = 1))
Error in f(1, 3, b = 1): argument 3 matches multiple formal arguments

Generally, you only want to use positional matching for the first one or two arguments. Avoid using positional matching for less commonly used arguments, and only use readable abbreviations with partial matching.

 Named arguments should always come after unnamed arguments. 

mean(1:10)
mean(1:10, trim = 0.05)

This is probably overkill:

mean(x = 1:10)

And these are just confusing:

mean(1:10, n = T)
mean(1:10, , FALSE)
mean(1:10, 0.05)
mean(, TRUE, x = c(1:10, NA))

Calling a function given a list of arguments

Suppose you had a list of function arguments:

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

Default and missing arguments

Function arguments in R can have default values.

f <- function(a = 1, b = 2) {
  c(a, b)
}
f()
#> [1] 1 2

Since arguments in R are evaluated lazily (more on that below), the default value can be defined in terms of other arguments:

g <- function(a = 1, b = a * 2) {
  c(a, b)
}
g()
#> [1] 1 2
g(10)
#> [1] 10 20

Default arguments can even be defined in terms of variables created within the function.

h <- function(a = 1, b = d) {
  d <- (a + 1) ^ 2
  c(a, b)
}
h()
#> [1] 1 4
h(10)
#> [1]  10 121

Similarly, you can determine if an argument was supplied or not with the missing() function.

i <- function(a, b) {
  c(missing(a), missing(b))
}
i()
#> [1] TRUE TRUE
i(a = 1)
#> [1] FALSE  TRUE
i(b = 2)
#> [1]  TRUE FALSE
i(1, 2)
#> [1] FALSE FALSE

Sometimes you want to add a non-trivial default value, which might take several lines of code to compute. Instead of inserting that code in the function definition, you could use missing() to conditionally compute it if needed.

Lazy evaluation

By default, R function arguments are lazy — they’re only evaluated if they’re actually used:

f <- function(x) {
  10
}
f(stop("This is an error!"))
#> [1] 10

If you want to ensure that an argument is evaluated you can use force():

f <- function(x) {
  force(x)
  10
}
f(stop("This is an error!"))
#> Error in force(x): This is an error!

This is important when creating closures with lapply() or a loop:

add <- function(x) {
  function(y) x + y
}
adders <- lapply(1:10, add)
adders[[1]](10)
#> [1] 11
adders[[10]](10)
#> [1] 20

Since x is lazily evaluated the first time that you call one of the adder functions. At this point, the loop is complete and the final value of x is 10. Therefore all of the adder functions will add 10 on to their input, probably not what you wanted! Manually forcing evaluation fixes the problem:

add <- function(x) {
  force(x)
  function(y) x + y
}
adders2 <- lapply(1:10, add)
adders2[[1]](10)
#> [1] 11
adders2[[10]](10)
#> [1] 20

This code is exactly equivalent to

add <- function(x) {
  x
  function(y) x + y
}

because the force function is defined as force <- function(x) x. However, using this function clearly indicates that you’re forcing evaluation, not that you’ve accidentally typed x.

Default arguments are evaluated inside the function. This means that if the expression depends on the current environment the results will differ depending on whether you use the default value or explicitly provide one.

f <- function(x = ls()) {
  a <- 1
  x
}
 
# ls() evaluated inside f:
f()
#> [1] "a" "x"
 
# ls() evaluated in global environment:
f(ls())
#>  [1] "add"     "adders"  "adders2" "args"    "f"       "funs"    "g"      
#>  [8] "h"       "i"       "objs"    "path"    "x"       "y"

Laziness is useful in if statements — the second statement below will be evaluated only if the first is true. If it wasn’t, the statement would return an error because NULL > 0 is a logical vector of length 0 and not a valid input to if.

x <- NULL
if (!is.null(x) && x > 0) {
 
}

Therefore, we could implement “&&” ourselves:

`&&` <- function(x, y) {
  if (!x) return(FALSE)
  if (!y) return(FALSE)
 
  TRUE
}
a <- NULL
!is.null(a) && a > 0
#> [1] FALSE

This function would not work without lazy evaluation because both x and y would always be evaluated, testing a > 0 even when a was NULL.

Sometimes you can also use laziness to eliminate an if statement altogether. For example, instead of:

if (is.null(a)) stop("a is null")
#> Error in eval(expr, envir, enclos): a is null

You could write:

!is.null(a) || stop("a is null")
#> Error in eval(expr, envir, enclos): a is null

Conclusion

Hence, we saw what are the different arguments in a function we can use. we also was how to implement those argument with each example.

This brings the end of this Blog. We really appreciate your time.

Hope you liked it.

Do visit our page www.zigya.com/blog for more informative blogs on Data Science

Keep Reading! Cheers!

Zigya Academy
BEING RELEVANT

Leave a Reply

Your email address will not be published.