0

I'm attempting to use tryCatch to skip instances of a function generating errors inside of a for loop so that the loop completes and generates output values in those instances where there are no errors. Here's a toy example whose output makes little sense to me:

list=list(10,20,"abc",30,40)
y=c()
for(x in list1){
   skip_to_next = FALSE
   temp=tryCatch(log(x), error = function(e) {skip_to_next = TRUE})
   if(skip_to_next) {next}
   y=c(y,temp)
}

If I execute this for loop, my output y is:

y
[1] 2.302585 2.995732 1.000000 3.401197 3.688879

I'm not sure where the 1.0 is coming from, log of a string throws an error and should just skip the third iteration entirely, i.e. return a 4-element vector with elements 1:2 and 4:5 of the above.

Evidently I'm not implementing tryCatch() or next correctly - why isn't "next" taking me to the next iteration as I thought it should?

I was referencing this previous stackoverflow discussion when writing my example:

Skipping error in for-loop

Max
  • 487
  • 5
  • 19
  • An alternative, avoiding a loop that grows an object*, would be: `list1 |> Filter(f = is.numeric) |> sapply(FUN = log)` * see Circle 2 in the R-Inferno: https://www.burns-stat.com/pages/Tutor/R_inferno.pdf – I_O Jun 17 '23 at 17:47

1 Answers1

1

You have to use the super-assignment:

tryCatch(log(x), error = function(e) {skip_to_next <<- TRUE})

In your code, you do

temp <- tryCatch(log(x), error = function(e) {skip_to_next = TRUE})

Then in temp you have the output of the error function, which is TRUE (see below) but it is coerced to 1 in the numeric vector y.

Here is why the output is TRUE:

f <- function() {
  a <- 2
}

print(f())
# 2
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225