10.7 安全函数

当循环迭代时遇到错误报错,导致整个程序停止,这不是我们能接受的,尤其时在做大规模比较耗时的工作时。purrr提供了“安全函数” possibly()safely()处理该类问题。

l <- list(1,2,3,4,'5')
map(l,function(.x) .x+1)
# Error in .x + 1 : 二进列运算符中有非数值参数

由于字符 5 不能相加,导致以上代码报错,不能正确运行。通过函数safely()改进函数,即可避免:

l <- list(1,2,3,4,'5')
test_fun <- safely(function(.x) .x+1)
map(l,test_fun)
#> [[1]]
#> [[1]]$result
#> [1] 2
#> 
#> [[1]]$error
#> NULL
#> 
#> 
#> [[2]]
#> [[2]]$result
#> [1] 3
#> 
#> [[2]]$error
#> NULL
#> 
#> 
#> [[3]]
#> [[3]]$result
#> [1] 4
#> 
#> [[3]]$error
#> NULL
#> 
#> 
#> [[4]]
#> [[4]]$result
#> [1] 5
#> 
#> [[4]]$error
#> NULL
#> 
#> 
#> [[5]]
#> [[5]]$result
#> NULL
#> 
#> [[5]]$error
#> <simpleError in .x + 1: 二进列运算符中有非数值参数>

用safely()函数将原始function包裹起来,即使执行过程中遇到错误也可以完成整个任务,不会因为中途报错停止,在大型循环过程中,如爬虫过程中比较实用。

或者用possibly()函数:

test_fun <- possibly(function(.x) .x+1,otherwise = NA)
map(l,test_fun)
#> [[1]]
#> [1] 2
#> 
#> [[2]]
#> [1] 3
#> 
#> [[3]]
#> [1] 4
#> 
#> [[4]]
#> [1] 5
#> 
#> [[5]]
#> [1] NA

使用默认值替换错误发生时的“值”

list("a", 10, 100) %>%
  map_dbl(possibly(log, NA_real_))
#> [1]   NA 2.30 4.61