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()
答案 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})
}
然后将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})))
最后,如果你想使用Vectorized函数,你可以完全跳过map
函数。但就个人而言,我从不使用Vectorize
,因此我会使用map
进行此操作。
data %>% mutate(y = Vectorize(try_my_func)(x))