Reputation: 4631
I'm using RStudio for writing code in R. Usually I submit larger chunks of code by selecting it and pressing Ctrl + Enter
. Now, When an error occurs (e.g. connection to a databse could not be established), I'd like to abort execution of the subsequent code.
I tried stop()
, which works when all the code is in one line:
# 21 is not shown
42; stop("error"); 21;
But when the code spans multiple lines, the code is still evaluated:
# Here 21 is shown
42
stop("error")
21
Is the a way to abort execution of code when submitting larger chunks of code?
Upvotes: 4
Views: 2210
Reputation: 12640
@DavidArenburg's answer is certainly the most straightforward approach. However, it's not clear from your question whether you wanted to preserve the behaviour of printing the value of each statement as it was run which is what happens normally when you use Ctrl-Enter in RStudio. If you did want to do that, then your options would be:
print
e.g.
{
print(42)
stop("error")
print(21)
}
#[1] 42
# Error: error
e.g.
block <- function(expr) {
expr <- substitute(expr)
for (i in seq(expr)[-1]) {
y <- withVisible(eval(expr[[i]], parent.frame()))
if (y$visible && i != length(expr)) print(y$value)
}
y$value
}
block({
42
stop("error")
21
})
#[1] 42
# Error in eval(expr, envir, enclos) : error
Note that in all cases, none of your statements will actually be executed until you finish the block.
For non-trivial blocks of code, the difference in execution speed is negligible compared to standard execution.
e.g.
microbenchmark::microbenchmark(block = block({
a <- 1:1e6
b <- rnorm(1e6)
sum(a + b)
}), curly = {
a <- 1:1e6
b <- rnorm(1e6)
sum(a + b)
})
#Unit: milliseconds
# expr min lq mean median uq max neval
# block 108.7961 130.2517 169.4891 176.8425 197.4749 299.4014 100
# curly 109.9183 134.3076 171.9430 174.7121 194.5748 292.5958 100
Upvotes: 2
Reputation: 92282
You can wrap your code between {}
(curly brackets) as they are pretty much equivalent to your ;
chain.
{
42
stop("error")
21
}
## Error: error
Here's a nice illustration from the documentations with a function like interface.
do <- get("{")
do(x <- 3, y <- 2*x-3, 6-x-y)
## [1] 0
x <- 3; y <- 2*x-3; 6-x-y
## [1] 0
Upvotes: 4