What's similar to an #ifdef DEBUG in R? - r

I'm writing R code where I would like to have it run either in "non-debug" or "debug" mode. Under the debug mode, I would like the code to print-out runtime information.
In other languages, I would typically have some sort of print function that does nothing unless a flag is turned on (either for compilation or runtime).
For example, I can use #ifdef DEBUG (in compilation time), or set a debug level in run time.
What would be the equivalent way of doing this in R?

Same thing, minus the preprocessor:
Define a global variable variable (or use an options() value)
Insert conditional code that tests for the variable
Works with your functions (adding ..., verbose=options(myVerbose)), in your packages, etc pp
I have also used it in R scripts (driven by littler) using the CRAN package getopt to pick up a command-line option --verbose or --debug.

A slightly fancier version of Dirk's answer:
is_debug_mode <- function()
{
exists(".DEBUG", envir = globalenv()) &&
get(".DEBUG", envir = globalenv())
}
set_debug_mode <- function(on = FALSE)
{
old_value <- is.debug.mode()
.DEBUG <<- on
invisible(old_value)
}
Usage is, e.g.,
if(is_debug_mode())
{
#do some logging or whatever
}
and
set_debug_mode(TRUE) #turn debug mode on
set_debug_mode(FALSE) #turn debug mode off

It might also be worth looking at the Verbose class in the R.utils package, which allows you very fine control for printing run-time information of various sorts.

Extending Richie's code:
also, you can check for the system environment variable DEBUG for initialization:
isdbg <- function()
{
if(exists(".DEBUG", envir = globalenv()))
{
return(get(".DEBUG", envir = globalenv()))
} else #initialise from shell environment variable
{
debugmode <- !(toupper(Sys.getenv("DEBUG")) %in% c("", "FALSE", "0"))
assign(".DEBUG", debugmode, envir = globalenv())
return(debugmode)
}
}
setdbg <- function(on = FALSE)
{
old_value <- isdbg()
.DEBUG <<- on
invisible(old_value)
}
ifdbg <- function(x)
{
if(isdbg()) x
}
usage:
setdbg(TRUE) #turn debug mode on
setdbg(FALSE) #turn debug mode off
if(isdbg())
{
#do some logging or whatever
}
or
ifdebug(...do something here...)

Another possibility is log4r
To quote this page:
log4r: A simple logging system for R, based on log4j
logr4 provides an object-oriented logging system that uses an API
roughly equivalent to log4j and its related variants.

Related

knitr: Create environment to share variables across chunks which are deleted when finished

I'm developing an R package (https://github.com/rcst/rmaxima) that provides an interface to the computer algebra system Maxima. I want to include a knitr engine, so that it can directly be used with knitr. The package has functions to start/ spawn a child process and then send commands to and fetch results from Maxima. This way, it should be possible to carry over results between different chunks.
The interface works by creating a new object of an Rcpp-class of the interface. Creating the object spawns a child process, deleting the objects stops that process.
I want the engine to start a new child process each time the document is knit()ed, so that the result is reproducible. I'm thinking that I could create an extra environment that binds the interface object. The engine checks whether this objects exists in that environment. If it doesn't exist, it will be created, otherwise the engine can directly proceed to send code to the interface. When knit() exits, it exits the scope of it's environment and all variables within that environment are deleted automatically. This way, I need not stop the child process, because the object of the interface class get's deleted and the process is stopped automatically.
But I have no clue how to go about it. Any hints very much appreciated.
yihui provides an answer here.
In essence, (a) one sets a temporary variable in the parent frame to check if the engine is running and (b) inspects the lists of chunk labels to determine if the current one is the last and therefore trigger deletion and tear down after it's been processed:
last_label <- function(label = knitr::opts_current$get('label')) {
if (knitr:::child_mode()) return(FALSE)
labels <- names(knitr::knit_code$get())
tail(labels, 1) == label
}
knitr::knit_engines$set(maxima = local({
mx <- FALSE
function(options) {
if (!mx) {
maxima$startMaxima()
mx <<- TRUE
}
... # run maxima code
if (last_label(options$label)) {
maxima$stopMaxima()
mx <<- FALSE
}
}
}))
For completeness, I also came up with a solution which works, but is less robust.
Objects that go out of scope are automatically removed in R. However, actual deletion happens during R's garbage collection gc(), which cannot be controlled directly. So to get an object removed when knit() finishes, that object needs to be created in the environment of knit(), which is some levels above the engine call.
In principle one can register a function that does the actual clean-up via on.exit() of knit(), who's environment can be retrieved by parent.frame(n=...). Note that all objects of that scope are still present the moment the expressions registered to on.exit() get called.
maxima.engine <- function(options) {
e <- parent.frame(n = sys.parent() - 2)
if(!exists("mx", envir = e)) {
message("starting maxima on first chunk")
assign(x = "mx", value = new(rmaxima:::RMaxima), envir = e)
assign(x = "execute", value = get("mx", envir = e)$execute, envir = e)
assign(x = "stopMaxima", value = get("mx", envir = e)$stopMaxima, envir = e)
# quit maxima "on.exit"ing of knit()
# eval() doesn't work on "special primitive functions
# do.call() does ... this may break in the future
# see https://stat.ethz.ch/pipermail/r-devel/2013-November/067874.html
do.call("on.exit", list(quote(stopMaxima()),
add = TRUE), envir = e)
}
code <- options$code
out <- character(0);
for(i in 1:length(code))
out <- c(out, eval(call("execute", code[i]), envir = e))
engine_output(options, code, out)
}

Invoke interrupt from R code

I have a generic function to catch all exceptions included in my package logR::tryCatch2 defined as:
tryCatch2 <- function(expr){
V=E=W=M=I=NULL
e.handler = function(e){
E <<- e
NULL
}
w.handler = function(w){
W <<- c(W, list(w))
invokeRestart("muffleWarning")
}
m.handler = function(m){
attributes(m$call) <- NULL
M <<- c(M, list(m))
}
i.handler = function(i){
I <<- i
NULL
}
V = suppressMessages(withCallingHandlers(
tryCatch(expr, error = e.handler, interrupt = i.handler),
warning = w.handler,
message = m.handler
))
list(value=V, error=E, warning=W, message=M, interrupt=I)
}
As you can see in the last line it returns a list which is more or less self describing.
It makes the real reaction to the exceptions delayed after the tryCatch2 call by simple !is.null:
f = function(){ warning("warn1"); warning("warn2"); stop("err") }
r = tryCatch2(f())
if(!is.null(r$error)) cat("Error detected\n")
# Error detected
if(!is.null(r$warning)) cat("Warning detected, count", length(r$warning), "\n")
# Warning detected, count 2
It works as expected, I can react with my own code. But in some cases I would like to not stop the interrupt process which is caught too. At the moment it seems I would need to add additional parameter to tryCatch2 which would control if interrupts should be catch or not. So the question asks about some invokeInterrupt function which I could use in the following way:
g = function(){ Sys.sleep(60); f() }
r = tryCatch2(g())
# interrupt by pressing ctrl+c / stop while function is running!
if(!is.null(r$interrupt)) cat("HERE I would like to invoke interrupt\n")
# HERE I would like to invoke interrupt
I think if R is able to catch one it should be also able to invoke one.
How can I achieve invokeInterrupt functionality?
I can propose a partial solution, which relies on the tools package.
invokeInterrupt <- function() {
require(tools)
processId <- Sys.getpid()
pskill(processId, SIGINT)
}
However, be aware that throwing the interrupt signal (SIGINT) with pskill doesn't appear to be very robust. I ran a few tests by sending the exception and catching it with your function, like so:
will_interrupt <- function() {
Sys.sleep(3)
invokeInterrupt()
Sys.sleep(3)
}
r = tryCatch2(will_interrupt())
On linux, this worked well when executed from the R commandline. On windows, the R commandline and R Gui did close when executing this code. There is worse: on both linux and windows, this code crashed Rstudio instantly...
So, if your code is to be executed from the R commandline on Linux, this solution should be OK. Otherwise you might be out of luck...
Late answer but I have found that rlang::interrupt can throw "user interrupts":
interrupt() allows R code to simulate a user interrupt of the kind that is signalled with Ctrl-C.
It is currently not possible to create custom interrupt condition objects.
Source: ?rlang::interrupt
Internally it calls the R API function Rf_onintr which is an alias for the function onintr.
Basically an interrupt is "just" a special condition with these classes:
interrupt and condition (see the R source code).
If you just want to simulate an interrupt to test tryCatching (without the need to interrupt a running R statement) it suffice to throw a condition with these classes via signalCondition:
interrupt_condition <- function() {
structure(list(), class = c("interrupt", "condition"))
}
tryCatch(signalCondition(interrupt_condition()),
interrupt = function(x) print("interrupt detected"))
# [1] "interrupt detected"

Clearing environment from within script

I'd like to clear the environment during a script run.
I am using of the (slightly changed) function which i've seen here
clearEnv <- function(env = parent.frame())
{
rm(list = setdiff( ls(all.names=TRUE, env = env), lsf.str(all.names=TRUE, env = env)),envir = env)
}
But this only works outside of a script. I want to call this function in-script of my personal R package before anything else is saved as variable.
Is there a way of doing this? Maybe nesting the function somewhere?
Thank you!
EDIT:
Thought it was clear enough - obviously not, so here is a minimal example:
script.R has two functions
clearEnv <- function(env = parent.frame())
{
rm(list = setdiff( ls(all.names=TRUE, env = env), lsf.str(all.names=TRUE, env = env)),envir = env)
}
myScript <- function(){
clearEnv()
/*do work*/
}
-- This does not work. I see that it is not clearing the environment at all, because when I save a variable, say thisShouldVanish <- 0, before running myScript(), it is still there afterwards.
If I run
clearEnv()
myScript()
it is working as expected, but I want to run myScript() only instead of separating the two function calls...
I mentioned, that this functions are part of a package, so neither these function nor anything else has to be in the environment -> it should be okay to delete mid-run.
I hope I was able to explain it better.

Stopping an R script quietly and return control to the terminal [duplicate]

Is there any way to stop an R program without error?
For example I have a big source, defining several functions and after it there are some calls to the functions. It happens that I edit some function, and want the function definitions to be updated in R environment, but they are not actually called.
I defined a variable justUpdate and when it is TRUE want to stop the program just after function definitions.
ReadInput <- function(...) ...
Analyze <- function(...) ...
WriteOutput <- function(...) ...
if (justUpdate)
stop()
# main body
x <- ReadInput()
y <- Analyze(x)
WriteOutput(y)
I have called stop() function, but the problem is that it prints an error message.
ctrl+c is another option, but I want to stop the source in specific line.
The problem with q() or quit() is that it terminates R session, but I would like to have the R session still open.
As #JoshuaUlrich proposed browser() can be another option, but still not perfect, because the source terminates in a new environment (i.e. the R prompt will change to Browser[1]> rather than >). Still we can press Q to quit it, but I am looking for the straightforward way.
Another option is to use if (! justUpdate) { main body } but it's clearing the problem, not solving it.
Is there any better option?
I found a rather neat solution here. The trick is to turn off all error messages just before calling stop(). The function on.exit() is used to make sure that error messages are turned on again afterwards. The function looks like this:
stop_quietly <- function() {
opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
stop()
}
The first line turns off error messages and stores the old setting to the variable opt. After this line, any error that occurs will not output a message and therfore, also stop() will not cause any message to be printed.
According to the R help,
on.exit records the expression given as its argument as needing to be executed when the current function exits.
The current function is stop_quietly() and it exits when stop() is called. So the last thing that the program does is call options(opt) which will set show.error.messages to the value it had, before stop_quietly() was called (presumably, but not necessarily, TRUE).
There is a nice solution in a mailing list here that defines a stopQuietly function that basically hides the error shown from the stop function:
stopQuietly <- function(...) {
blankMsg <- sprintf("\r%s\r", paste(rep(" ", getOption("width")-1L), collapse=" "));
stop(simpleError(blankMsg));
} # stopQuietly()
> stopQuietly()
I have a similar problem and, based on #VangelisTasoulas answer, I got a simple solution.
Inside functions, I have to check if DB is updated. If it is not, stop the execution.
r=readline(prompt="Is DB updated?(y/n)")
Is DB updated?(y/n)n
if(r != 'y') stop('\r Update DB')
Update DB
Just putting \r in the beginning of the message, overwrite Error: in the message.
You're looking for the function browser.
You can use the following solution to stop an R program without error:
if (justUpdate)
return(cat(".. Your Message .. "))
Just return something at the line you want to quit the function:
f <- function(x, dry=F) {
message("hi1")
if (dry) return(x)
message("hi2")
x <- 2*x
}
y1 <- f(2) # = 4 hi1 hi2
y2 <- f(2, dry=T) # = 2 hi1
In addition to answer from Stibu on Mar 22 '17 at 7:29, if you want to write a message as a part of stop(), this message is not written.
I perceive strange that following two lines have to be used meaning on.exit(options(options(show....))) doesn't work.
opt <- options(show.error.messages = F)
on.exit(options(opt))
I had forgotten the answer to this and needed to look it up and landed here... You posted the hint to the answer in your question...
ctrl+c is another option, but I want to stop the source in specific line.
Signal an error, warning, or message
rlang::inform("Updated Only")
rlang::interrupt()
I've found it good to write a script and run it with source(). In the script, a write exit statements as a special class of error that a tryCatch() can pick up and send back as just a message:
exit <- function(..., .cl = NULL) {
# Use to capture acceptable stop
cond <- structure(
list(.makeMessage(...), .cl),
class = c("exitError", "error", "condition"),
names = c("message", "call")
)
stop(cond)
}
foo <- function() {
exit("quit here")
1
}
tryCatch(
# rather than foo(), you might use source(filename)
foo(),
exitError = function(e) message(e$message)
)
#> quit here
Created on 2022-01-24 by the reprex package (v2.0.1)
You can use with_options() in the withr package to temporarily disable error messages and then you can call stop() directly.
Here is an example:
weird_math <- function(x, y, z) {
if (x > z) {
withr::with_options(
list(show.error.messages = FALSE),
{
print("You can execute other code here if you want")
stop()
}
)
}
# only runs if x <= z
x + y ^ z
}
weird_math(1, 2, 3)
[1] 9
weird_math(3, 2, 1)
[1] "You can execute other code here if you want"
why not just use an if () {} else {}? It's only a couple of characters...
f1 <- function(){}
f2 <- function(){}
if (justUpdate) {
} else {
# main body
}
or even
f1 <- function(){}
f2 <- function(){}
if (!justUpdate) {
# main body
}
The below code work for me stopped without error messages.
opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
break

Stop an R program without error

Is there any way to stop an R program without error?
For example I have a big source, defining several functions and after it there are some calls to the functions. It happens that I edit some function, and want the function definitions to be updated in R environment, but they are not actually called.
I defined a variable justUpdate and when it is TRUE want to stop the program just after function definitions.
ReadInput <- function(...) ...
Analyze <- function(...) ...
WriteOutput <- function(...) ...
if (justUpdate)
stop()
# main body
x <- ReadInput()
y <- Analyze(x)
WriteOutput(y)
I have called stop() function, but the problem is that it prints an error message.
ctrl+c is another option, but I want to stop the source in specific line.
The problem with q() or quit() is that it terminates R session, but I would like to have the R session still open.
As #JoshuaUlrich proposed browser() can be another option, but still not perfect, because the source terminates in a new environment (i.e. the R prompt will change to Browser[1]> rather than >). Still we can press Q to quit it, but I am looking for the straightforward way.
Another option is to use if (! justUpdate) { main body } but it's clearing the problem, not solving it.
Is there any better option?
I found a rather neat solution here. The trick is to turn off all error messages just before calling stop(). The function on.exit() is used to make sure that error messages are turned on again afterwards. The function looks like this:
stop_quietly <- function() {
opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
stop()
}
The first line turns off error messages and stores the old setting to the variable opt. After this line, any error that occurs will not output a message and therfore, also stop() will not cause any message to be printed.
According to the R help,
on.exit records the expression given as its argument as needing to be executed when the current function exits.
The current function is stop_quietly() and it exits when stop() is called. So the last thing that the program does is call options(opt) which will set show.error.messages to the value it had, before stop_quietly() was called (presumably, but not necessarily, TRUE).
There is a nice solution in a mailing list here that defines a stopQuietly function that basically hides the error shown from the stop function:
stopQuietly <- function(...) {
blankMsg <- sprintf("\r%s\r", paste(rep(" ", getOption("width")-1L), collapse=" "));
stop(simpleError(blankMsg));
} # stopQuietly()
> stopQuietly()
I have a similar problem and, based on #VangelisTasoulas answer, I got a simple solution.
Inside functions, I have to check if DB is updated. If it is not, stop the execution.
r=readline(prompt="Is DB updated?(y/n)")
Is DB updated?(y/n)n
if(r != 'y') stop('\r Update DB')
Update DB
Just putting \r in the beginning of the message, overwrite Error: in the message.
You're looking for the function browser.
You can use the following solution to stop an R program without error:
if (justUpdate)
return(cat(".. Your Message .. "))
Just return something at the line you want to quit the function:
f <- function(x, dry=F) {
message("hi1")
if (dry) return(x)
message("hi2")
x <- 2*x
}
y1 <- f(2) # = 4 hi1 hi2
y2 <- f(2, dry=T) # = 2 hi1
In addition to answer from Stibu on Mar 22 '17 at 7:29, if you want to write a message as a part of stop(), this message is not written.
I perceive strange that following two lines have to be used meaning on.exit(options(options(show....))) doesn't work.
opt <- options(show.error.messages = F)
on.exit(options(opt))
I had forgotten the answer to this and needed to look it up and landed here... You posted the hint to the answer in your question...
ctrl+c is another option, but I want to stop the source in specific line.
Signal an error, warning, or message
rlang::inform("Updated Only")
rlang::interrupt()
I've found it good to write a script and run it with source(). In the script, a write exit statements as a special class of error that a tryCatch() can pick up and send back as just a message:
exit <- function(..., .cl = NULL) {
# Use to capture acceptable stop
cond <- structure(
list(.makeMessage(...), .cl),
class = c("exitError", "error", "condition"),
names = c("message", "call")
)
stop(cond)
}
foo <- function() {
exit("quit here")
1
}
tryCatch(
# rather than foo(), you might use source(filename)
foo(),
exitError = function(e) message(e$message)
)
#> quit here
Created on 2022-01-24 by the reprex package (v2.0.1)
You can use with_options() in the withr package to temporarily disable error messages and then you can call stop() directly.
Here is an example:
weird_math <- function(x, y, z) {
if (x > z) {
withr::with_options(
list(show.error.messages = FALSE),
{
print("You can execute other code here if you want")
stop()
}
)
}
# only runs if x <= z
x + y ^ z
}
weird_math(1, 2, 3)
[1] 9
weird_math(3, 2, 1)
[1] "You can execute other code here if you want"
why not just use an if () {} else {}? It's only a couple of characters...
f1 <- function(){}
f2 <- function(){}
if (justUpdate) {
} else {
# main body
}
or even
f1 <- function(){}
f2 <- function(){}
if (!justUpdate) {
# main body
}
The below code work for me stopped without error messages.
opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
break

Resources