3 minute read

Polymorphic Functions�������������������������������������������������������������������������������������������������

Chapter 9 ■ advanCed r programming

The difference in interface between the two functions is just that vapply expects a third parameter that should be a value of the type the output should be.

Advertisement

vapply(1:3, function(x) x**2, 1) ## [1] 1 4 9

Advanced Functions

We now get to some special cases for functions. I call the section “Advanced Functions,” but not because they really are that advanced, only that they require a little bit more than the basic functions you have already seen.

Special Names

But first a word on names. Functions can have the same kind of names that variables have—after all, when we name a function, we are really just naming a variable that happens to hold a function—but we cannot have all kinds of names to the right of the assignment operator. For example, if is a function in R, but you cannot write if to the left of an assignment.

Functions with special names, that is names that you couldn’t normally put before an assignment, can be referred to by putting them in backticks, so the function if we can refer to as if.

Any function can be referred to by its name in backticks and furthermore you can use backticks to refer to a function in a context where you usually couldn’t use its name. This works for calling functions where you can use for example infix operators as normal function calls:

2 + 2 ## [1] 4 `+`(2, 2) ## [1] 4

Or when assigning to a variable name for a function:

`%or die%` <- function(test, msg) if (!test) stop(msg)

x <- 5 (x != 0) %or die% "x should not be zero"

x <- 0 (x != 0) %or die% "x should not be zero" ## Error in (x != 0) %or die% "x should not be zero": x should not be zero

Infix Operators

If the last example looks weird to you, it may just be because you don’t know about R’s infix operators. In R, any variable that starts and ends with % is considered an infix operator, so calling x %foo% y amounts to calling `%foo%`(x,y). Several built-in infix operators do not have this type of name, + and * are two, but this naming convention makes it possible to create your own infix operators. You saw this come to good use in the dplyr package with the %>% pipe operator.

242

Chapter 9 ■ advanCed r programming

Replacement Functions

Replacement functions are functions that pretend to be modifying variables. You saw one early when you assigned names to a vector.

v <- 1:4 names(v) <- c("a", "b", "c", "d") v ## a b c d ## 1 2 3 4

What happens here is that R recognizes that you are assigning to a function call and goes looking for a function named names<-. It calls this function with the vector v and the vector of names and the result of the function call gets assigned back to the variable v.

So what I just wrote means that this:

names(v) <- c("a", "b", "c", "d")

Is short for this:

v <- `names<-`(v, c("a", "b", "c", "d"))

Replacement functions are generally used to modify various attributes of an object, and you can write your own just by using the convention that their names must end with <-:

`foo<-` <- function(x, value) { x$foo <- value x

`bar<-` <- function(x, value) { x$bar <- value x

x <- list(foo=1, bar=2)

x$foo ## [1] 1 foo(x) <- 3 x$foo ## [1] 3 x$bar ## [1] 2 bar(x) <- 3 x$bar ## [1] 3

243

This article is from: