Alguém tem exemplos / tutoriais de tratamento de exceções em R? A documentação oficial é muito concisa.
Alguém tem exemplos / tutoriais de tratamento de exceções em R? A documentação oficial é muito concisa.
Respostas:
Além da resposta de Shane apontando para outras discussões StackOverflow, você pode tentar um recurso de pesquisa de código. Esta resposta original apontava para a Pesquisa de código do Google que foi descontinuada, mas você pode tentar
Apenas para registro, existe também, try
mas tryCatch
pode ser preferível. Eu tentei uma contagem rápida no Google Code Search, mas tentei obter muitos falsos positivos para o próprio verbo - mas parece que tryCatch
é mais amplamente usado.
Basicamente, você deseja usar a tryCatch()
função. Veja a ajuda ("tryCatch") para mais detalhes.
Aqui está um exemplo trivial (tenha em mente que você pode fazer o que quiser com um erro):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Dê uma olhada nessas questões relacionadas:
Este resultado de uma pesquisa do Google relacionada me ajudou: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
A função trycatch()
é bastante simples e existem muitos bons tutoriais sobre isso. Uma excelente explicação do tratamento de erros em R pode ser encontrada no livro Advanced-R de Hadley Wickham , e o que se segue é uma introdução muito básica withCallingHandlers()
e withRestarts()
com o mínimo de palavras possível:
Digamos que um programador de baixo nível escreva uma função para calcular o valor absoluto. Ele não tem certeza de como calculá-lo, mas sabe como construir um erro e transmite diligentemente sua ingenuidade:
low_level_ABS <- function(x){
if(x<0){
#construct an error
negative_value_error <- structure(
# with class `negative_value`
class = c("negative_value","error", "condition"),
list(message = "Not Sure what to with a negative value",
call = sys.call(),
# and include the offending parameter in the error object
x=x))
# raise the error
stop(negative_value_error)
}
cat("Returning from low_level_ABS()\n")
return(x)
}
Um programador de nível médio também escreve uma função para calcular o valor absoluto, fazendo uso da low_level_ABS
função lamentavelmente incompleta . Ele sabe que o código de baixo nível gera um negative_value
erro quando o valor de x
é negativo e sugere uma solução para o problema, estabelecendo umrestart
que permite aos usuários de mid_level_ABS
controlar a forma como se mid_level_ABS
recupera (ou não) de um negative_value
erro.
mid_level_ABS <- function(y){
abs_y <- withRestarts(low_level_ABS(y),
# establish a restart called 'negative_value'
# which returns the negative of it's argument
negative_value_restart=function(z){-z})
cat("Returning from mid_level_ABS()\n")
return(abs_y)
}
Finalmente, um programador de alto nível usa o mid_level_ABS
função para calcular o valor absoluto e estabelece um manipulador de condição que diz ao
mid_level_ABS
para se recuperar de um negative_value
erro usando o manipulador de reinicialização.
high_level_ABS <- function(z){
abs_z <- withCallingHandlers(
# call this function
mid_level_ABS(z) ,
# and if an `error` occurres
error = function(err){
# and the `error` is a `negative_value` error
if(inherits(err,"negative_value")){
# invoke the restart called 'negative_value_restart'
invokeRestart('negative_value_restart',
# and invoke it with this parameter
err$x)
}else{
# otherwise re-raise the error
stop(err)
}
})
cat("Returning from high_level_ABS()\n")
return(abs_z)
}
O ponto de tudo isso é que usando withRestarts()
e withCallingHandlers()
, a função
high_level_ABS
foi capaz de dizer mid_level_ABS
como se recuperar de erros levantados porlow_level_ABS
erro sem interromper a execução de
mid_level_ABS
, que é algo que você não pode fazer com tryCatch()
:
> high_level_ABS(3)
Returning from low_level_ABS()
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
> high_level_ABS(-3)
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
Na prática, low_level_ABS
representa uma função que mid_level_ABS
chama muito (talvez até milhões de vezes), para a qual o método correto de tratamento de erros pode variar de acordo com a situação, e a escolha de como tratar erros específicos é deixada para funções de nível superior ( high_level_ABS
).
A função de reinicialização é muito importante no R herdado do Lisp. É útil se você deseja chamar alguma função no corpo do loop e deseja apenas que o programa continue se a chamada da função for interrompida. Experimente este código:
for (i in 1:20) withRestarts(tryCatch(
if((a <- runif(1))>0.5) print(a) else stop(a),
finally = print("loop body finished!")),
abort = function(){})