byo*_*ess 4 exception-handling r dplyr mutate
dplyr中是否有任何异常处理机制mutate()?我的意思是捕获异常并处理异常的方法。
让我们假设我有一个函数在某些情况下会引发错误(在示例中,如果输入为负),为简单起见,我定义了该函数,但实际上,它将是某些R包中的函数。让我们假设此函数是矢量化的:
# 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)
Run Code Online (Sandbox Code Playgroud)
现在,假设我要在内部使用此函数mutate()。
如果在a中使用此函数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.
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以捕获错误,并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
Run Code Online (Sandbox Code Playgroud)
您想单独评估每个发生的错误,也许您不应该使用矢量化函数。而是map从包中使用 -purrr这实际上与lapply此处相同。
如果在出现错误的情况下需要 NA 值,请创建一个函数来捕获错误以用于标准用途。
try_my_func <- function(x) {
tryCatch(my_func(x), error = function(err){NA})
}
Run Code Online (Sandbox Code Playgroud)
然后,使用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
Run Code Online (Sandbox Code Playgroud)
或者类似地,如果您不想声明一个新函数。
data %>% mutate(y = purrr::map(x, ~ tryCatch(my_func(.), error = function(err){NA})))
Run Code Online (Sandbox Code Playgroud)
最后,如果您确实想使用矢量化函数,则可以map完全跳过该函数。但我个人从不使用,Vectorize所以我会用map.
data %>% mutate(y = Vectorize(try_my_func)(x))
Run Code Online (Sandbox Code Playgroud)
我们也可以利用purrr的safely()或possibly()功能。
从purrr帮助中:
安全地:包装函数返回包含组件结果和错误的列表。一个值始终为NULL。
悄悄地:包装函数返回一个包含组件结果,输出,消息和警告的列表。
可能:每当发生错误时,包装函数都会使用默认值(否则)。
您不必将函数分别应用于每一行,这一事实并没有改变。
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))
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
其他功能在“数据框环境”中使用和应用起来有些困难,因为它们更适合于使用列表并返回。
由reprex软件包(v0.2.0)创建于2018-05-15 。
| 归档时间: |
|
| 查看次数: |
876 次 |
| 最近记录: |