Notas sobre R - UB · Function evaluation I Functions are evaluated by associating the values of...

26
Outline Presentation, overview, references Introduction Data Conditional executions Functions Lexical Scoping and Computing on the Language

Transcript of Notas sobre R - UB · Function evaluation I Functions are evaluated by associating the values of...

Outline

Presentation, overview, referencesIntroductionDataConditional executionsFunctionsLexical Scoping and Computing on the Language

Functions

I It is possible to expand R’s capabilities by modifying existingfunctions and to easily write custom functions.

I In fact, most of the R software can be viewed as a series of Rfunctions.

I The value returned by a function is the value of the functionbody, which is usually an unassigned final expression.

Syntax

myfct <- function(arg1, arg2, ...) functionBody

Creating new functions

I Functions are defined by

1. Assignment with the keyword ’function’,2. The declaration of arguments/variables (arg1, arg2, ...) and3. The definition of operations (functionbody) that perform

computations on the provided arguments.

I A simple example.

> square <- function(x) x * x

> square(10)

[1] 100

> square(1:5)

[1] 1 4 9 16 25

Naming and overwriting

I A function name needs to be assigned to call the function.

I Function names can be almost anything.

I Functions that a user writes have the same status as thosewhich are provided with R .

I If a user creates a function with the same name that anexisting one (let it be or not a system function) the newfunction has preference over the old one.

Function evaluation

I Functions are evaluated by associating the values of thearguments with the names of the formal parameters and thenevaluating the body of the function using these associations.

I If the function hypot is defined by:

> hypot = function(a, b) sqrt(a^2 + b^2)

then the S expression hypot(3, 4) is evaluated as follows.I Temporarily create variables a and b, which have the values 3

and 4I Use these variables definitions to evaluate the expression

sqrt(a^2 + b^2)

to obtain the value 5.I When the evaluation is complete remove the temporary

definitions of a and b.

Arguments: mandatory or optional

I Arguments are values which are passed to the function to beused in computations.

I It is often useful to provide default values for arguments(example: arg1=1:10}).

I These make it possible for arguments to take on reasonabledefault values if no values was specified in the call to thefunction.

> sumsq <- function(x, about = 0) sum((x - about)^2)

I This means that the expressions sumsq(1:10, 0) andsumsq(1:10) are equivalent and will return the same value.

Optional Arguments

I The default values for arguments can be specified by an Sexpression involving the variables available inside the body ofthe function

> sumsq = function(x, about = mean(x)) sum((x - about)^2)

I Recursive references within default arguments are notpermitted. E.g. at least one argument must be provided tothe following function

> silly = function(a = b, b = a) a + b

Example: Function with optional arguments

> myfct2 <- function(x1 = 5, opt_arg) {

+ if (missing(opt_arg)) {

+ z1 <- 1:4

+ }

+ else {

+ z1 <- opt_arg

+ }

+ cat("my function returns:", "\n")

+ print(z1/x1)

+ }

> myfct2(x1 = 5)

my function returns:[1] 0.2 0.4 0.6 0.8

> myfct2(x1 = 5, opt_arg = 5:10)

my function returns:[1] 1.0 1.2 1.4 1.6 1.8 2.0

Argument Matching

I Because it is not necessary to specify all the arguments to Sfunction, it is important to be clear about which argumentcorresponds to which formal parameter of the function.

I The solution is to indicate which formal parameter isassociated with an argument by providing a (partial) name forthe argument.

I In the case of the sumsq function, the following are equivalent:

> sumsq(1:10, mean(1:10))

> sumsq(1:10, about = mean(1:10))

> sumsq(1:10, a = mean(1:10))

Argument Matching

I The arguments that the function is called with are called theactuals. The arguments that appear in the definition of thefunction are called the formals

I First, arguments are matched by name, using exact matching

I Second, partial matching of arguments is carried out

I Third, remaining unmatched arguments are matched byposition

Examples

> myfct <- function(x1, x2 = 5) {

+ z1 <- x1/x1

+ z2 <- x2 * x2

+ cat("my function returns:", "\n")

+ print(c(z1, z2))

+ }

> myfct(x1 = 2, x2 = 5)

my function returns:[1] 1 25

> myfct(x2 = 5, x = 1)

my function returns:[1] 1 25

myfct(x=5,x=1) # does the same as before,Error in myfct(x = 5, x = 1) : formal argument "x1"matched by multiple actual arguments

Lazy Evaluation

I S differs from many computer languages because theevaluation of function arguments is lazy

I In other words, arguments are not actually evaluated untilthey are required.

I It can be the case that arguments are never evaluated.

Example

I Here is a variation of the sumsq function.

> sumsq <- function(x, about = mean(x)) {

+ x = x[!is.na(x)]

+ sum((x - about)^2)

+ }

I This function first removes any NA values from x beforecomputing its answer.

I Lazy evaluation means that the about value is computed afterx has been cleaned

Terminating a function: return, warning, stop

I Return The evaluation flow of a function may be terminatedat any stage with the ’return()’ function. This is often used incombination with conditional evaluations.

I Stop To stop the action of a function and print an errormessage, one can use the stop() function.

I Warning To print a warning message in unexpected situationswithout aborting the evaluation flow of a function, one canuse the function ’warning(”...”)’.

Example: Actions on errors

> myfct <- function(x1) {

+ if (x1 >= 0)

+ print(x1)

+ else stop("Function stopped (x1 < 0")

+ warning("Value needs to be > 0")

+ }

> myfct(x1=2); myfct(x1=-2)[1] 2Warning message:In myfct(x1 = 2) : Value needs to be > 0Error en myfct(x1 = -2) :Function stopped (x1 < 0

Control of Evaluation

I In some cases you want to evaluate a function that may fail,but you do not want to exit from the middle of an evaluation

I In these cases the function try can be used

I try(expr) will either return the value of the expression expr,or an object of class tryerror

I tryCatch provides a much more substantial mechanism forcondition handling and error recovery.

e <- simpleError("test error")tryCatch(stop(e), finally=print("Hello"))

Closing Things

I Sometimes you will want to make sure that global parameters(say in options) are reset, or files are closed, when you exit afunction

I And often you want to ensure that these are reset even if anerror or some other nonlocal exit occurs

I In these cases you should use on.exit; it allows you to placeexpressions into a list to be evaluated

> f <- function(x) {

+ on.exit(print("hi"))

+ }

Outline

Presentation, overview, referencesIntroductionDataConditional executionsFunctionsLexical Scoping and Computing on the Language

Computing on the language

I Because argument evaluation is lazy, S allows programmers toget access to the unevaluated arguments.

I This is made possible by the substitute function.

> g = function(x) substitute(x)

> g(x[1] + y * 2)

x[1] + y * 2

I substitute is used in conjunction with deparse to obtain acharacter string representation of an argument.

> g = function(x) deparse(substitute(x))

> g(x[1] + y * 2)

[1] "x[1] + y * 2"

Computing on the language

I The substitute function can take a call and substitute thesymbolic representation of several arguments

> g <- function(a, b) substitute(a + b)

> g(x * x, y * y)

x * x + y * y

I One particularly useful trick is to use the “...” argument in asubstitute expression

> g = function(...) substitute(list(...))

> g(a = 10, b = 11)

list(a = 10, b = 11)

Scoping

I Weve seen that evaluation is the process of determining thevalue of a symbolic expression.

I In order for evaluation to take place, values must bedetermined for the variables in the expression.

I The scope of a variable is that portion of a program wherethat variable refers to the same value.

I The two dialects of S differ in their scoping rules.

Example

I In the following fragment:

> x = 10

> y = 20

> f = function(y) {

+ x + y

+ }

I There is a global variable called x.

I There is a global variable called y and a local variable called y.

Scoping in R

I R uses what is called static, or lexical scoping (another term isblock structure)

I Variables defined in outer blocks are visible inside inner blocks

I This is a natural extension to the SPlus way of scoping

I The hiding of helper functions within wrappers is encourage

I This promotes better software design and alleviates namespace clutter.

I It also has some interesting consequences.

Example: Gaussian Likelihoods

I The following code works in R, but not SPlus, since it relieson lexical scope

> mkNegLogLik = function(x) {

+ function(mu, sigma) {

+ sum(sigma + 0.5 * ((x - mu)/sigma)^2)

+ }

+ }

> q = mkNegLogLik(rnorm(100))

I What is q? How does it work?

Name Spaces

I Name spaces were introduced in R 1.7.0, see R News, Vol 3/1for more details.

I They provide a mechanism that allows package writers tocontrol what functions they import (and hence use) andexport (and hence let others use).

I They allow a package author to use a function from anotherpackage without attaching it to the search list.

I However, name spaces cause some problems and interfere withsome of the ways users like to interact with R.

Name Spaces

I Functions that are not exported from a name space are noteasily viewed by the user.

I Functions that are exported from a name space can beaccessed by using the doublecolon, “::”, operator

I This is a binary operator, its first operand is the name of thepackage and the second is the name of the function, e.gbase::mean

I To access a function that is not exported you need to use thetriplecolon operator. E.g.aPackage:::anUnexportedFunction.

I This should only be done for the purposes of investigation.

I If a package author does not export a function, they typicallyhave a reason for that