I would like to call a function on each element of a list and store the results, warnings and errors in a data frame. I came up with the following solution, which is neither well-tested nor pretty - so I would be interested in a better way.
library(purrr)
myf <- function(a){
if(a == 1){
return(a)
}else if(a == 2){
warning("a warning")
return(a)
}else if(a == 3){
stop("an error")
}
}
a = 1:3
safe_and_quiet <- function(fun, ...){
safe_fun <- quietly(safely(fun))
out_safe <- safe_fun(...)
out <-
list(
result = out_safe$result$result,
error = out_safe$result$error,
output = out_safe$output,
warnings = out_safe$warnings,
messages = out_safe$messages)
if(!is.null(out$error)){
out$error <- conditionMessage(out$error)
}
out <- map(out, null_to_na)
return(out)
}
null_to_na <- function(obj){
if(is.null(obj)|(length(obj)==0)){
return(NA)
}else{
return(obj)
}
}
res <- map_dfr(a, ~safe_and_quiet(myf, .x))
which gives the desired output
# A tibble: 3 x 5
result error output warnings messages
<int> <chr> <chr> <chr> <lgl>
1 1 NA "" NA NA
2 2 NA "" a warning NA
3 NA an error "" NA NA
So I need a combination of safely and quietly as well as outputs that are not NULL or vectors of length 0 to be able to create a data frame.