在dplyr的mutate里面尝试tryCatch?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在dplyr的mutate里面尝试tryCatch?相关的知识,希望对你有一定的参考价值。

在dplyr qazxsw poi中是否有任何异常处理机制?我的意思是捕获异常并处理它们的方法。

让我们假设我有一个在某些情况下抛出错误的函数(在示例中,如果输入是负数),为了简单起见我定义了函数,但在现实生活中它将是某个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()
答案

我们也可以使用y <- rep(NA_real_, length(data$x)) for(i in seq_along(data$x)) { tryCatch({ y[i] <- my_func_vect(data$x[i]) }, error = function(err){}) } y # Result is: 1 NA 2 4 purrrsafely()函数。

来自possibly()的帮助:

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

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

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

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

purrr

With map:

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))

Using 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()

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

data %>% rowwise() %>% mutate(y = possibly(my_func_vect, otherwise = NA_real_)(x)) #> Source: local data frame [4 x 2] #> Groups: <by row> #> #> # A tibble: 4 x 2 #> x y #> <dbl> <dbl> #> 1 1 1 #> 2 -1 NA #> 3 4 2 #> 4 9 3 创建于2018-05-15(v0.2.0)。

另一答案

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

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

lapply

然后使用try_my_func <- function(x) { tryCatch(my_func(x), error = function(err){NA}) } mutate

map

或者类似地,如果您不想声明新功能。

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}))) 函数。但我个人从来没有使用map所以我会用Vectorize做。

map

以上是关于在dplyr的mutate里面尝试tryCatch?的主要内容,如果未能解决你的问题,请参考以下文章

dplyr包实用总结之mutate系列

你能让 dplyr::mutate 和 dplyr::lag 默认 = 自己的输入值吗?

在 R 中:将列名作为参数传递,并在 dplyr::mutate() 和 lazyeval::interp() 的函数中使用它

使用dplyr :: mutate后,为什么给定的属性会消失?

在 dplyr mutate_at 调用中使用多列的函数

R语言dplyr包使用mutate函数生成新的数据列(不改变原数据列)实战