How to skip an error in a loop

前端 未结 4 1259
庸人自扰
庸人自扰 2020-12-05 00:36

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

4条回答
  •  孤街浪徒
    2020-12-05 01:12

    This would put NULLs 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.

    Edit:

    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.

提交回复
热议问题