让我们用一个简单的例子 log() 来说明:
safe_log <- safely(log) str(safe_log(10)) #> List of 2 #> $ result: num 2.3 #> $ error : NULL str(safe_log("a")) #> List of 2 #> $ result: NULL #> $ error :List of 2 #> ..$ message: chr "non-numeric argument to mathematical ..." #> ..$ call : language .f(...) #> ..- attr(*, "class")= chr [1:3] "simpleError" "error" ...
当函数成功执行时,result 元素包含结果,而 error 元素为 NULL。当函数失败时,result 元素为 NULL,而 error 元素包含一个错误对象。
safely() 旨在与 map 配合使用:
x <- list(1, 10, "a") y <- x %>% map(safely(log)) str(y) #> List of 3 #> $ :List of 2 #> ..$ result: num 0 #> ..$ error : NULL #> $ :List of 2 #> ..$ result: num 2.3 #> ..$ error : NULL #> $ :List of 2 #> ..$ result: NULL #> ..$ error :List of 2 #> .. ..$ message: chr "non-numeric argument to ..." #> .. ..$ call : language .f(...) #> .. ..- attr(*, "class")=chr [1:3] "simpleError" "error" ...
如果我们有两个列表会更容易处理:一个包含所有错误,另一个包含所有输出。使用 purrr::transpose() 可以轻松实现:
y <- y %>% transpose() str(y) #> List of 2 #> $ result:List of 3 #> ..$ : num 0 #> ..$ : num 2.3 #> ..$ : NULL #> $ error :List of 3 #> ..$ : NULL