1

I'm running a complicated function (multiple imputation with Amelia) over a list of datasets. Every so often, a dataset will trigger a long list of warnings that eventually result in an error. I would like R to give up as soon as the first warning is issued and move on to the next dataset. Here is a minimal working example:

df.list <- list(
  data.frame(1:4), 
  data.frame(-1, -2,  -4), 
  data.frame(10:15)
)

for(df in df.list){
  ans <- sum(sapply(df, sqrt))
  print(ans)
}

The script issues three warnings about NaNs and then prints:

[1] 6.146264
[1] NaN
[1] 21.1632

I would like it to produce 1 message input 2 failed and then output only the valid results:

[1] 6.146264
[1] 21.1632

(The function I'm actually running, amelia(), issues warnings for 10 minutes before finally throwing an error, so I would like to cut it off at the first warning.)

conflictcoder
  • 383
  • 1
  • 9
  • 1
    Turn your warnings into errors: https://stackoverflow.com/questions/8217901/breaking-loop-when-warnings-appear-in-r . Then take the place where you call your code on the data set, and wrap it in `try`. – David T May 26 '20 at 04:13

1 Answers1

0

What about this: the sqrt function cannot return -1 so I make tryCatch return -1 when a warning occurs. The nested lapply is required to loop through the list elements to calculate the square root, returned as a list, and then to loop through those list elements to sum. The -1 value in the result indicates a failed calculation and I can test that.

result <- unlist(
  lapply(
    lapply(df.list, function(x) tryCatch(sqrt(x), warning = function(w) -1)), sum))
failed <- which(result == -1)
result <- result[-failed]
print(paste0("input ", failed, " failed"))
result

> print(paste0("input ", failed, " failed"))
[1] "input 2 failed"
> result
[1]  6.146264 21.163196
Paul van Oppen
  • 1,443
  • 1
  • 9
  • 18