I want to skip an error (if there is any) in a loop and continue the next iteration. I want to compute 100 inverse matrices of a 2 by 2 matrix with elements randomly sampled from {0, 1, 2}. It is possible to have a singular matrix (for example,
1 0 2 0
Here is my code
set.seed(1) count <- 1 inverses <- vector(mode = "list", 100) repeat { x <- matrix(sample(0:2, 4, replace = T), 2, 2) inverses[[count]] <- solve(x) count <- count + 1 if (count > 100) break }
At the third iteration, the matrix is singular and the code stops running with an error message. In practice, I would like to bypass this error and continue to the next loop. I know I need to use a try
or tryCatch
function but I don't know how to use them. Similar questions have been asked here, but they are all really complicated and the answers are far beyond my understanding. If someone can give me a complete code specifically for this question, I really appreciate it.
The simplest way of handling conditions in R is to simply ignore them: Ignore errors with try() . Ignore warnings with suppressWarnings() .
You can use a continue statement in Python to skip over part of a loop when a condition is met. Then, the rest of a loop will continue running. You use continue statements within loops, usually after an if statement.
The sys. exc_clear() statement can be utilized to clear the last thrown exception of the Python interpreter. The following code uses the sys. exc_clear() statement in the except block to ignore an exception and proceed with the code in Python.
The next statement in R programming language is useful when we want to skip the current iteration of a loop without terminating it. On encountering next, the R parser skips further evaluation and starts next iteration of the loop.
This would put NULL
s into inverses
for the singular matrices:
inverses[[count]] <- tryCatch(solve(x), error=function(e) NULL)
If the first expression in a call to tryCatch
raises an error, it executes and returns the value of the function supplied to its error
argument. The function supplied to the error
arg has to take the error itself as an argument (here I call it e
), but you don't have to do anything with it.
You could then drop the NULL
entries with inverses[! is.null(inverses)]
.
Alternatively, you could use the lower level try
. The choice is really a matter of taste.
count <- 0 repeat { if (count == 100) break count <- count + 1 x <- matrix(sample(0:2, 4, replace = T), 2, 2) x.inv <- try(solve(x), silent=TRUE) if ('try-error' %in% class(x.inv)) next else inverses[[count]] <- x.inv }
If your expression generates an error, try
returns an object with class try-error
. It will print the message to screen if silent=FALSE
. In this case, if x.inv
has class try-error
, we call next
to stop the execution of the current iteration and move to the next one, otherwise we add x.inv
to inverses
.
You could avoid using the repeat
loop with replicate
and lapply
.
matrices <- replicate(100, matrix(sample(0:2, 4, replace=T), 2, 2), simplify=FALSE) inverses <- lapply(matrices, function(mat) if (det(mat) != 0) solve(mat))
It's interesting to note that the second argument to replicate
is treated as an expression
, meaning it gets executed afresh for each replicate. This means you can use replicate
to make a list
of any number of random objects that are generated from the same expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With