在dplyr的mutate里面尝试tryCatch?

时间:2018-05-14 16:27:00

标签: r exception-handling dplyr mutate

dplyr的defer中是否存在任何异常处理机制?我的意思是捕捉异常并处理它们的方法。

让我们假设我有一个在某些情况下抛出错误的函数(在示例中,如果输入是负数),为了简单起见我定义了函数,但在现实生活中它将是一个函数R包。让我们假设这个函数是矢量化的:

mutate()

现在,假设我想在# function throwing an error my_func <- function(x){ if(x > 0) return(sqrt(x)) stop('x must be positive') } my_func_vect <- Vectorize(my_func) 内使用此功能。

如果在mutate()内使用此函数,它会在第一个错误处停止,并且不会返回任何结果:

mutate()

有没有办法捕获错误,并在这种情况下执行某些操作(例如,返回library(dplyr) # dummy data data <- data.frame(x = c(1, -1, 4, 9)) data %>% mutate(y = my_func_vect(x)) # Error in mutate_impl(.data, dots) : Evaluation error: x must be positive. ),同时获取其他元素的结果?

我期望的结果是使用NA的循环可以实现的结果,即:

tryCatch()

2 个答案:

答案 0 :(得分:5)

我们还可以使用purrr的{​​{1}}或safely()函数。

来自possibly()帮助:

  

安全:包装函数返回一个包含组件结果和错误的列表。一个值始终为NULL。

     

安静地:包装函数返回一个包含组件结果,输出,消息和警告的列表。

     

可能:包装函数在发生错误时使用默认值(否则)。

它不会改变你必须分别将函数应用于每一行的事实。

purrr

使用地图:

library(dplyr)
library(purrr)

# function throwing an error
my_func <- function(x){
  if(x > 0) return(sqrt(x))
  stop('x must be positive')
}

my_func_vect <- Vectorize(my_func)

# dummy data
data <- data.frame(x = c(1, -1, 4, 9))

使用data %>% mutate(y = map_dbl(x, ~possibly(my_func_vect, otherwise = NA_real_)(.x))) #> x y #> 1 1 1 #> 2 -1 NA #> 3 4 2 #> 4 9 3

rowwise()

其他功能在“数据框架环境”中更难以使用和应用,因为它们更适合使用列表,并返回这些功能。

reprex package(v0.2.0)创建于2018-05-15。

答案 1 :(得分:1)

您想要单独评估每个发生的错误,也许您不应该使用矢量化函数。而是使用map包中的purrr - 这与lapply实际上相同。

如果在出现错误的情况下需要NA值,请创建一个函数来捕获标准使用的错误。

try_my_func <- function(x) {
  tryCatch(my_func(x), error = function(err){NA})
}

然后将mutatemap

一起使用
data %>% mutate(y = purrr::map(x, try_my_func))
   x  y
1  1  1
2 -1 NA
3  4  2
4  9  3

或类似地,如果您不想宣布新功能。

data %>% mutate(y = purrr::map(x, ~ tryCatch(my_func(.), error = function(err){NA})))

最后,如果你想使用Vectorized函数,你可以完全跳过map函数。但就个人而言,我从不使用Vectorize,因此我会使用map进行此操作。

data %>% mutate(y = Vectorize(try_my_func)(x))