Sie sind auf Seite 1von 60

Debugging and Tuning R Functions

R.M. Ripley

Department of Statistics
University of Oxford

2012/13

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 1 / 29


R Exception Handling Introduction

R Exception Handling

Exceptions are conditions which prevent R’s normal processing.


Some are so serious that processing cannot continue. Others are
less serious but R suspects they are unexpected, so will indicate
their occurrence.
The term exception handling refers to methods of dealing with
exceptions.
Two common types of exceptions are warnings and errors.
Various options control R’s exception handling.
The function try() can be wrapped around code which might fail,
to allow the writer of the code rather then R to deal with the
exception.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 2 / 29


R Exception Handling Options

Use of R options

Options are used to control many different aspects of R. A list of


options and their current settings can be obtained by options().

Some examples of options:


digits suggested number of digits to use when printing
numbers. Default 7.
contrasts controls use of factor variables in model fitting. Default:
for unordered factors is "contr.treatment", for ordered
factors, "contr.poly".
help-type character string indicating the type of help preferred.
Possible values are "text", "html" and "pdf".

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 3 / 29


R Exception Handling Options

Use of R options

Options are used to control many different aspects of R. A list of


options and their current settings can be obtained by options().

Some examples of options:


digits suggested number of digits to use when printing
numbers. Default 7.
contrasts controls use of factor variables in model fitting. Default:
for unordered factors is "contr.treatment", for ordered
factors, "contr.poly".
help-type character string indicating the type of help preferred.
Possible values are "text", "html" and "pdf".

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 3 / 29


R Exception Handling Options

Use of R options, continued

Note that many available options are not set by default. Some are
set as packages are loaded.

The options available can be found by using the help system: the
page for options contains a detailed description.

Options used as default values for functions (e.g. na.action in


lm) will be mentioned on the help page for the function.

To set an option: options(digits=5)

To access a specific option:


getOption("digits")
or
options("digits")

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 4 / 29


R Exception Handling Options

Use of R options, continued

Note that many available options are not set by default. Some are
set as packages are loaded.

The options available can be found by using the help system: the
page for options contains a detailed description.

Options used as default values for functions (e.g. na.action in


lm) will be mentioned on the help page for the function.

To set an option: options(digits=5)

To access a specific option:


getOption("digits")
or
options("digits")

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 4 / 29


R Exception Handling Options

Use of R options, continued

Note that many available options are not set by default. Some are
set as packages are loaded.

The options available can be found by using the help system: the
page for options contains a detailed description.

Options used as default values for functions (e.g. na.action in


lm) will be mentioned on the help page for the function.

To set an option: options(digits=5)

To access a specific option:


getOption("digits")
or
options("digits")

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 4 / 29


R Exception Handling Errors

R exception handling: Errors

Serious exceptions but not catastrophic: R cannot continue, but is


still able to do something e.g. cannot find a variable.
Default behaviour: print a message and return to prompt.
Error messages can be suppressed by
options(show.error.messages=FALSE).
options(error) can be set to the name of a function which will
be called in the case of an error.
Default options(error) is NULL, in which case processing
stops.
Two useful alternatives are:
recover allows browsing on any currently active function
dump.frames dumps the currently active functions. Dump can be
examined using debugger, which is similar to
recover
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 5 / 29
R Exception Handling Errors

R exception handling: Errors

Serious exceptions but not catastrophic: R cannot continue, but is


still able to do something e.g. cannot find a variable.
Default behaviour: print a message and return to prompt.
Error messages can be suppressed by
options(show.error.messages=FALSE).
options(error) can be set to the name of a function which will
be called in the case of an error.
Default options(error) is NULL, in which case processing
stops.
Two useful alternatives are:
recover allows browsing on any currently active function
dump.frames dumps the currently active functions. Dump can be
examined using debugger, which is similar to
recover
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 5 / 29
R Exception Handling Errors

R exception handling: Errors

Serious exceptions but not catastrophic: R cannot continue, but is


still able to do something e.g. cannot find a variable.
Default behaviour: print a message and return to prompt.
Error messages can be suppressed by
options(show.error.messages=FALSE).
options(error) can be set to the name of a function which will
be called in the case of an error.
Default options(error) is NULL, in which case processing
stops.
Two useful alternatives are:
recover allows browsing on any currently active function
dump.frames dumps the currently active functions. Dump can be
examined using debugger, which is similar to
recover
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 5 / 29
R Exception Handling Errors

R exception handling: Errors

Serious exceptions but not catastrophic: R cannot continue, but is


still able to do something e.g. cannot find a variable.
Default behaviour: print a message and return to prompt.
Error messages can be suppressed by
options(show.error.messages=FALSE).
options(error) can be set to the name of a function which will
be called in the case of an error.
Default options(error) is NULL, in which case processing
stops.
Two useful alternatives are:
recover allows browsing on any currently active function
dump.frames dumps the currently active functions. Dump can be
examined using debugger, which is similar to
recover
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 5 / 29
R Exception Handling Errors

R exception handling: Errors

Serious exceptions but not catastrophic: R cannot continue, but is


still able to do something e.g. cannot find a variable.
Default behaviour: print a message and return to prompt.
Error messages can be suppressed by
options(show.error.messages=FALSE).
options(error) can be set to the name of a function which will
be called in the case of an error.
Default options(error) is NULL, in which case processing
stops.
Two useful alternatives are:
recover allows browsing on any currently active function
dump.frames dumps the currently active functions. Dump can be
examined using debugger, which is similar to
recover
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 5 / 29
R Exception Handling Errors

R exception handling: Errors

Serious exceptions but not catastrophic: R cannot continue, but is


still able to do something e.g. cannot find a variable.
Default behaviour: print a message and return to prompt.
Error messages can be suppressed by
options(show.error.messages=FALSE).
options(error) can be set to the name of a function which will
be called in the case of an error.
Default options(error) is NULL, in which case processing
stops.
Two useful alternatives are:
recover allows browsing on any currently active function
dump.frames dumps the currently active functions. Dump can be
examined using debugger, which is similar to
recover
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 5 / 29
R Exception Handling Warnings

R exception handling: Warnings

Less serious exceptions, e.g. NA’s produced when converting


character data to numeric

Behaviour controlled by value of options(warn):


< 0 warnings are ignored
0 (default) warnings are stored till top level function returns.
Then, if there are no more than 10 warnings, they are
displayed. If there are more than 10, a message saying how
many (max 50) have been generated is displayed
1 prints warning immediately it is generated
>= 2 treats a warning as an error

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 6 / 29


R Exception Handling Warnings

R exception handling: Warnings

Less serious exceptions, e.g. NA’s produced when converting


character data to numeric

Behaviour controlled by value of options(warn):


< 0 warnings are ignored
0 (default) warnings are stored till top level function returns.
Then, if there are no more than 10 warnings, they are
displayed. If there are more than 10, a message saying how
many (max 50) have been generated is displayed
1 prints warning immediately it is generated
>= 2 treats a warning as an error

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 6 / 29


R Exception Handling Warnings

R exception handling: Warnings

Less serious exceptions, e.g. NA’s produced when converting


character data to numeric

Behaviour controlled by value of options(warn):


< 0 warnings are ignored
0 (default) warnings are stored till top level function returns.
Then, if there are no more than 10 warnings, they are
displayed. If there are more than 10, a message saying how
many (max 50) have been generated is displayed
1 prints warning immediately it is generated
>= 2 treats a warning as an error

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 6 / 29


Checking and Improving your functions Overview

Possible outcomes

You run your new function. It may


1 terminate successfully with no warnings
2 terminate successfully with anticipated warnings
e.g. NA’s produced when converting character data to numeric
3 terminate successfully with unexpected warnings
4 stop with a predictable error e.g. invalid arguments supplied
5 stop with an unpredictable error
In case 4, rerun the function with the correct input. In cases 1 and 2,
check the results and then consider profiling your function. Cases 3
and 5 are the problem: you need to find the error in your code.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 7 / 29


Checking and Improving your functions Overview

Possible outcomes

You run your new function. It may


1 terminate successfully with no warnings
2 terminate successfully with anticipated warnings
e.g. NA’s produced when converting character data to numeric
3 terminate successfully with unexpected warnings
4 stop with a predictable error e.g. invalid arguments supplied
5 stop with an unpredictable error
In case 4, rerun the function with the correct input. In cases 1 and 2,
check the results and then consider profiling your function. Cases 3
and 5 are the problem: you need to find the error in your code.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 7 / 29


Checking and Improving your functions Overview

Possible outcomes

You run your new function. It may


1 terminate successfully with no warnings
2 terminate successfully with anticipated warnings
e.g. NA’s produced when converting character data to numeric
3 terminate successfully with unexpected warnings
4 stop with a predictable error e.g. invalid arguments supplied
5 stop with an unpredictable error
In case 4, rerun the function with the correct input. In cases 1 and 2,
check the results and then consider profiling your function. Cases 3
and 5 are the problem: you need to find the error in your code.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 7 / 29


Checking and Improving your functions Overview

Possible outcomes

You run your new function. It may


1 terminate successfully with no warnings
2 terminate successfully with anticipated warnings
e.g. NA’s produced when converting character data to numeric
3 terminate successfully with unexpected warnings
4 stop with a predictable error e.g. invalid arguments supplied
5 stop with an unpredictable error
In case 4, rerun the function with the correct input. In cases 1 and 2,
check the results and then consider profiling your function. Cases 3
and 5 are the problem: you need to find the error in your code.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 7 / 29


Checking and Improving your functions Overview

Possible outcomes

You run your new function. It may


1 terminate successfully with no warnings
2 terminate successfully with anticipated warnings
e.g. NA’s produced when converting character data to numeric
3 terminate successfully with unexpected warnings
4 stop with a predictable error e.g. invalid arguments supplied
5 stop with an unpredictable error
In case 4, rerun the function with the correct input. In cases 1 and 2,
check the results and then consider profiling your function. Cases 3
and 5 are the problem: you need to find the error in your code.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 7 / 29


Checking and Improving your functions Overview

Possible outcomes

You run your new function. It may


1 terminate successfully with no warnings
2 terminate successfully with anticipated warnings
e.g. NA’s produced when converting character data to numeric
3 terminate successfully with unexpected warnings
4 stop with a predictable error e.g. invalid arguments supplied
5 stop with an unpredictable error
In case 4, rerun the function with the correct input. In cases 1 and 2,
check the results and then consider profiling your function. Cases 3
and 5 are the problem: you need to find the error in your code.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 7 / 29


Checking and Improving your functions Debugging functions

How to find the error


Debugging tools

One way to trace errors is to add cat or print statements where you
think they might be enlightening. But R provides several tools for more
powerful debugging. They are also useful for checking intermediate
results.
traceback() Prints the sequence of calls that led to the last error.
browser() Inserted into a function, interrupts it and allows access
to the R interpreter.
debug() Sets a debugging flag on a function: equivalent to
browser() at start of function. undebug() unsets
the flag
trace() Similar to debug but more powerful. untrace()
unsets the flag
recover() Allows browsing on any currently active function call.
Often used as an error option.
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 8 / 29
Checking and Improving your functions Debugging functions

How to find the error


Debugging tools

One way to trace errors is to add cat or print statements where you
think they might be enlightening. But R provides several tools for more
powerful debugging. They are also useful for checking intermediate
results.
traceback() Prints the sequence of calls that led to the last error.
browser() Inserted into a function, interrupts it and allows access
to the R interpreter.
debug() Sets a debugging flag on a function: equivalent to
browser() at start of function. undebug() unsets
the flag
trace() Similar to debug but more powerful. untrace()
unsets the flag
recover() Allows browsing on any currently active function call.
Often used as an error option.
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 8 / 29
Checking and Improving your functions Debugging functions

How to find the error


Debugging tools

One way to trace errors is to add cat or print statements where you
think they might be enlightening. But R provides several tools for more
powerful debugging. They are also useful for checking intermediate
results.
traceback() Prints the sequence of calls that led to the last error.
browser() Inserted into a function, interrupts it and allows access
to the R interpreter.
debug() Sets a debugging flag on a function: equivalent to
browser() at start of function. undebug() unsets
the flag
trace() Similar to debug but more powerful. untrace()
unsets the flag
recover() Allows browsing on any currently active function call.
Often used as an error option.
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 8 / 29
Checking and Improving your functions Debugging functions

How to find the error


Debugging tools

One way to trace errors is to add cat or print statements where you
think they might be enlightening. But R provides several tools for more
powerful debugging. They are also useful for checking intermediate
results.
traceback() Prints the sequence of calls that led to the last error.
browser() Inserted into a function, interrupts it and allows access
to the R interpreter.
debug() Sets a debugging flag on a function: equivalent to
browser() at start of function. undebug() unsets
the flag
trace() Similar to debug but more powerful. untrace()
unsets the flag
recover() Allows browsing on any currently active function call.
Often used as an error option.
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 8 / 29
Checking and Improving your functions Debugging functions

How to find the error


Debugging tools

One way to trace errors is to add cat or print statements where you
think they might be enlightening. But R provides several tools for more
powerful debugging. They are also useful for checking intermediate
results.
traceback() Prints the sequence of calls that led to the last error.
browser() Inserted into a function, interrupts it and allows access
to the R interpreter.
debug() Sets a debugging flag on a function: equivalent to
browser() at start of function. undebug() unsets
the flag
trace() Similar to debug but more powerful. untrace()
unsets the flag
recover() Allows browsing on any currently active function call.
Often used as an error option.
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 8 / 29
Checking and Improving your functions Debugging functions

traceback
Use after the error: no forward planning required

Example of traceback()
library(MASS)
lda(Sex ~ FL + CL + CW + RW + BD, crabs)
Error in eval(expr,envir,enclos):object "Sex" not
found
traceback()
9: eval(expr, envir, enclos)
8: eval(predvars, data, env)
7: model.frame.default(formula = Sex ~ FL + CL + CW +
RW + BD, data = crabs)
6: model.frame(formula = Sex ~ FL + CL + CW + RW +
BD, data = crabs)
5: eval(expr, envir, enclos)
4: eval(expr, p)
3: eval.parent(m)
2: lda.formula(Sex ~ FL + CL + CW + RW + BD, crabs)
1: lda(Sex ~ FL + CL + CW + RW + BD, crabs)
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 9 / 29
Checking and Improving your functions Debugging functions

browser()

Need to set up before the function is run. Change the function either by
usual route, or use fix(myfn) to leave your source file unchanged.
Add a call to browser() before the place you suspect the error
occurs. Rerun the job: R will stop with a prompt labelled "Browse":

Example of browser()
mymat<- cbind(1:4,c(1,4:6),4:7)
fn1(mymat)
Error in if (nmul > 1) nmul^3 else nmul^2 :
argument is of length zero
fix(fn1)
fn1(mymat)
Called from: fn1(mymat)
Browse[1]>

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 10 / 29


Checking and Improving your functions Debugging functions

browser()

Need to set up before the function is run. Change the function either by
usual route, or use fix(myfn) to leave your source file unchanged.
Add a call to browser() before the place you suspect the error
occurs. Rerun the job: R will stop with a prompt labelled "Browse":

Example of browser()
mymat<- cbind(1:4,c(1,4:6),4:7)
fn1(mymat)
Error in if (nmul > 1) nmul^3 else nmul^2 :
argument is of length zero
fix(fn1)
fn1(mymat)
Called from: fn1(mymat)
Browse[1]>

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 10 / 29


Checking and Improving your functions Debugging functions

Use of browser

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands:
c or cont or just return: leave the browser and continue at the
next statement

n enter the step through debugger

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt
Note than to examine a variable called c, cont, n, where, or Q, use
print()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 11 / 29


Checking and Improving your functions Debugging functions

Use of browser

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands:
c or cont or just return: leave the browser and continue at the
next statement

n enter the step through debugger

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt
Note than to examine a variable called c, cont, n, where, or Q, use
print()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 11 / 29


Checking and Improving your functions Debugging functions

Use of browser

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands:
c or cont or just return: leave the browser and continue at the
next statement

n enter the step through debugger

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt
Note than to examine a variable called c, cont, n, where, or Q, use
print()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 11 / 29


Checking and Improving your functions Debugging functions

Use of browser

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands:
c or cont or just return: leave the browser and continue at the
next statement

n enter the step through debugger

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt
Note than to examine a variable called c, cont, n, where, or Q, use
print()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 11 / 29


Checking and Improving your functions Debugging functions

Use of browser

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands:
c or cont or just return: leave the browser and continue at the
next statement

n enter the step through debugger

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt
Note than to examine a variable called c, cont, n, where, or Q, use
print()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 11 / 29


Checking and Improving your functions Debugging functions

Use of browser

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands:
c or cont or just return: leave the browser and continue at the
next statement

n enter the step through debugger

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt
Note than to examine a variable called c, cont, n, where, or Q, use
print()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 11 / 29


Checking and Improving your functions Debugging functions

Example of use of browser(), continued


browser()
The function
fn1<- function(mat){
mults <- mat[mat[, 1]==mat[, 2], ]
nmul<- nrow(mults)
browser()
if (nmul > 1) nmul^3
else nmul^2 }
browser session
Called from: fn1(mymat)
Browse[1]> ls()
[1] "mat" "mults" "nmul"
Browse[1]> mults
[1] 1 1 4
Browse[1]> nrow(mults)
NULL ## R has dropped a dimension

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 12 / 29


Checking and Improving your functions Debugging functions

Example of use of browser(), continued


browser()
Fix the function
fn1<- function(mat){
mults <- mat[mat[,1]==mat[,2], , drop=FALSE]
nmul<- nrow(mults)
browser()
if (nmul > 1) nmul^3
else nmul^2 }
browser session
Called from: fn1(mymat)
Browse[1]> mults
[,1] [,2] [,3]
[1,] 1 1 4
Browse[1]> nrow(mults)
[1] 1
Browse[1]> c
[1] 1

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 13 / 29


Checking and Improving your functions Debugging functions

debug()

Alternative method for previous problem, using debug()

debug()
debug(fn1)
fn1(mymat)
debugging in: fn1(mymat)
debug: {
mults <- mat[mat[, 1] == mat[, 2], ]
nmul <- nrow(mults)
if (nmul > 1)
nmul^3
else nmul^2
}
Browse[2]>

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 14 / 29


Checking and Improving your functions Debugging functions

Use of debug()

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands, similar to those for browser()
(note c and n behave differently here)
c or cont : continue to the end of the current context (loop or
function)

n or just return: advance to the next step

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 15 / 29


Checking and Improving your functions Debugging functions

Use of debug()

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands, similar to those for browser()
(note c and n behave differently here)
c or cont : continue to the end of the current context (loop or
function)

n or just return: advance to the next step

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 15 / 29


Checking and Improving your functions Debugging functions

Use of debug()

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands, similar to those for browser()
(note c and n behave differently here)
c or cont : continue to the end of the current context (loop or
function)

n or just return: advance to the next step

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 15 / 29


Checking and Improving your functions Debugging functions

Use of debug()

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands, similar to those for browser()
(note c and n behave differently here)
c or cont : continue to the end of the current context (loop or
function)

n or just return: advance to the next step

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 15 / 29


Checking and Improving your functions Debugging functions

Use of debug()

Use the prompt like a normal one, and enter normal commands, but
there are a few special commands, similar to those for browser()
(note c and n behave differently here)
c or cont : continue to the end of the current context (loop or
function)

n or just return: advance to the next step

where print a stack trace of all active function calls

Q exit the browser and the current function and return to the
toplevel prompt

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 15 / 29


Checking and Improving your functions Debugging functions

Example of debug()

debug(), continued
Browse[2]> n
debug: mults <- mat[mat[, 1] == mat[, 2], ]
Browse[2]> n
debug: nmul <- nrow(mults)
Browse[2]> mults
[1] 1 1 4
Browse[2]> dim(mults)
NULL
Browse[2]> Q

undebug(fn1) ## remove the debugging flag from fn1

trace is similar, but with more facilities. Consult the help page for
more details.
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 16 / 29
Checking and Improving your functions Debugging functions

recover()

recover()
##set up error function
options(error=recover)
##run our function
fn1(mymat)
Error in if (nmul > 1) nmul^3 else nmul^2 :
argument is of length zero

Enter a frame number, or 0 to exit

1: fn1(mymat)

Selection:

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 17 / 29


Checking and Improving your functions Debugging functions

recover()
recover(), continued
Selection: 1
Called from: eval(expr, envir, enclos)
Browse[1]> ls()
[1] "mat" "mults" "nmul"
Browse[1]> dim(mults)
NULL
Browse[1]> mults
[1] 1 1 4
Browse[1]> c

Enter a frame number, or 0 to exit

1: fn1(mymat)

Selection: 0
>
Then fix the function and rerun
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 18 / 29
Checking and Improving your functions Trapping expected errors

try()

A wrapper for your function, which returns the normal return value,
unless there is an error, when it returns an object of class
"try-error"
If there is an error, it prints an error message, unless you have
suppressed error messages using
options(show.error.messages=FALSE) or used the
argument silent=TRUE.
Surround your function by
if (!inherits(x <- try(myfn(y)), "try-error"))
do normal processing
else
do error processing

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 19 / 29


Checking and Improving your functions Trapping expected errors

try() continued

try()
tmp <- try(solve(mymat[-3, ]))
inherits(tmp, "try-error")
[1] FALSE
tmp <- try(solve(mymat[-1, ]))
inherits(tmp, "try-error")
Error in solve.default(mymat[-1, ]) :
Lapack routine dgesv: system is exactly singular
[1] TRUE
tmp <- try(solve(mymat[-1, ]),silent=TRUE)
inherits(tmp, "try-error")
[1] TRUE

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 20 / 29


Checking and Improving your functions Trapping expected errors

tryCatch
More powerful alternative to try().

tryCatch(expr, ..., finally)

expr Here you put the code which might cause an error or warning

... Here you define handlers for e.g. errors or warnings

finally Here you put code which should always be run (unless your
error handler stops things dead!).

The ... can include handlers for conditions you have defined.

The return value after a trapped condition will have the class of
the return value from the last handler invoked.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 21 / 29


Checking and Improving your functions Trapping expected errors

tryCatch
More powerful alternative to try().

tryCatch(expr, ..., finally)

expr Here you put the code which might cause an error or warning

... Here you define handlers for e.g. errors or warnings

finally Here you put code which should always be run (unless your
error handler stops things dead!).

The ... can include handlers for conditions you have defined.

The return value after a trapped condition will have the class of
the return value from the last handler invoked.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 21 / 29


Checking and Improving your functions Trapping expected errors

tryCatch
More powerful alternative to try().

tryCatch(expr, ..., finally)

expr Here you put the code which might cause an error or warning

... Here you define handlers for e.g. errors or warnings

finally Here you put code which should always be run (unless your
error handler stops things dead!).

The ... can include handlers for conditions you have defined.

The return value after a trapped condition will have the class of
the return value from the last handler invoked.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 21 / 29


Checking and Improving your functions Trapping expected errors

tryCatch, continued
tmp<- tryCatch(solve(mymat[-3,]),error=function(e){
cat("Matrix inversion failed\n"); e})
tmp
[,1] [,2] [,3]
[1,] 0.1666667 -1.4166667 0.9166667
[2,] -0.5000000 0.7500000 -0.2500000
[3,] 0.3333333 0.1666667 -0.1666667
tmp <- tryCatch(solve(mymat[-1,]),error=function(e){
cat("Matrix inversion failed\n"); e})
Matrix inversion failed
tmp
<simpleError in solve.default(mymat[-1, ]): Lapack
routine dgesv: system is exactly singular>
class(tmp)
[1] "simpleError" "error" "condition"
tmp <- tryCatch(solve(mymat[-1, ]), error=function(e) e,
finally=print("END"))
[1] "END"
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 22 / 29
Checking and Improving your functions Profiling

Profiling

Now your function works perfectly, but it might be a bit slow.


If it is not slow, don’t change it!
Don’t waste your time thinking of clever ways to perform the
processing until you know what is taking the time.
Use the function Rprof() to tell you what is worth tweaking.

Rprof()
mymat <- matrix(runif(1000000),nrow=1000)
Rprof()
inefficientFn(mymat)
Rprof(NULL)
summaryRprof()

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 23 / 29


Checking and Improving your functions Profiling

Profiling: example function

inefficientFn
inefficientFn<- function(x)
{
tmp <- 0
for (i in 1:nrow(x))
{
b <- exp(1/1:ncol(x))
tmp <- tmp + x[i,] * b
}
sum(tmp)
}

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 24 / 29


Checking and Improving your functions Profiling

Profiling: sample output


summaryRprof output
$by.self
self.time self.pct total.time total.pct
inefficientFn 0.06 42.9 0.14 100.0
exp 0.06 42.9 0.06 42.9
* 0.02 14.3 0.02 14.3

$by.total
total.time total.pct self.time self.pct
inefficientFn 0.14 100.0 0.06 42.9
exp 0.06 42.9 0.06 42.9
* 0.02 14.3 0.02 14.3

$sampling.time
[1] 0.14
R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 25 / 29
Checking and Improving your functions Profiling

Profiling: improved function

moreEfficientFn
moreEfficientFn<- function(x)
{
tmp <- 0
b <- exp(1/1:ncol(x))
for (i in 1:nrow(x))
{
tmp <- tmp + x[i,] * b
}
sum(tmp)
}

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 26 / 29


Checking and Improving your functions Profiling

Profiling: new output

Now the call to exp() does not use up significant time.

summaryRprof output
$by.self
self.time self.pct total.time total.pct
moreEfficientFn 0.04 100 0.04 100

$by.total
total.time total.pct self.time self.pct
moreEfficientFn 0.04 100 0.00 100

$sampling.time
[1] 0.04

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 27 / 29


Checking and Improving your functions Profiling

Profiling: timings

Timing the functions, using system.time shows the improvement


achieved.
system timings
system.time(inefficientFn(mymat))
user system elapsed
0.19 0.00 0.19

system.time(moreEfficientFn(mymat))
user system elapsed
0.06 0.00 0.07

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 28 / 29


Exercises

Exercises

Use the techniques while writing the project.

R.M. Ripley (University of Oxford) Debugging R Functions 2012/13 29 / 29

Das könnte Ihnen auch gefallen