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.
This would put
NULL
s intoinverses
for the singular matrices:If the first expression in a call to
tryCatch
raises an error, it executes and returns the value of the function supplied to itserror
argument. The function supplied to theerror
arg has to take the error itself as an argument (here I call ite
), but you don't have to do anything with it.You could then drop the
NULL
entries withinverses[! is.null(inverses)]
.Alternatively, you could use the lower level
try
. The choice is really a matter of taste.If your expression generates an error,
try
returns an object with classtry-error
. It will print the message to screen ifsilent=FALSE
. In this case, ifx.inv
has classtry-error
, we callnext
to stop the execution of the current iteration and move to the next one, otherwise we addx.inv
toinverses
.Edit:
You could avoid using the
repeat
loop withreplicate
andlapply
.It's interesting to note that the second argument to
replicate
is treated as anexpression
, meaning it gets executed afresh for each replicate. This means you can usereplicate
to make alist
of any number of random objects that are generated from the same expression.The documentation for try explains your problem pretty well. I suggest you go through it completely.
Edit:
The documentation example looked pretty straightforward and very similar to the op's question. Thanks for the suggestion though. Here goes the answer following the example in the documentation page:Instead of using
tryCatch
you could simply calculate the determinant of the matrix with the functiondet
. A matrix is singular if and only if the determinant is zero.Hence, you could test whether the determinant is different from zero and calculate the inverse only if the test is positive:
Update:
It is, however, possible to avoid generating singular matrices. The determinant of a 2-by-2 matrix
mat
is definded asmat[1] * mat[4] - mat[3] * mat[2]
. You could use this knowledge for sampling random numbers. Just do not sample numbers which will produce a singular matrix. This, of course, depends on the numbers sampled before.This procedure is a guarantee that all generated matrices will have an inverse.
try
is just a way of tellingR
: "If you commit an error inside the following parentheses, then skip it and move on."So if you're worried that
x <- matrix(sample(0:2, 4, replace = T), 2, 2)
might give you an error, then all you have to do is:However, keep in mind then that
x
will be undefined if you do this and it ends up not being able to compute the answer. That could cause a problem when you get tosolve(x)
- so you can either definex
beforetry
or just "try" the whole thing: