Có ai có ví dụ / hướng dẫn xử lý ngoại lệ trong R không? Các tài liệu chính thức là rất ngắn gọn.
Có ai có ví dụ / hướng dẫn xử lý ngoại lệ trong R không? Các tài liệu chính thức là rất ngắn gọn.
Câu trả lời:
Bên cạnh câu trả lời của Shane hướng dẫn bạn đến các cuộc thảo luận StackOverflow khác, bạn có thể thử tính năng tìm kiếm mã. Câu trả lời ban đầu này chỉ đến Tìm kiếm mã của Google đã ngừng hoạt động, nhưng bạn có thể thử
Chỉ đối với hồ sơ, cũng có try
nhưng tryCatch
có thể tốt hơn. Tôi đã thử đếm nhanh tại Google Code Search nhưng thử thì nhận được quá nhiều dương tính sai cho chính động từ - nhưng nó có vẻ tryCatch
được sử dụng rộng rãi hơn.
Về cơ bản bạn muốn sử dụng tryCatch()
chức năng. Xem phần trợ giúp ("tryCatch") để biết thêm chi tiết.
Đây là một ví dụ nhỏ (hãy nhớ rằng bạn có thể làm bất cứ điều gì bạn muốn với một lỗi):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Hãy xem những câu hỏi liên quan sau:
Kết quả này từ một tìm kiếm liên quan trên google đã giúp tôi: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
Chức năng trycatch()
này khá đơn giản và có rất nhiều hướng dẫn tốt về điều đó. Bạn có thể tìm thấy lời giải thích tuyệt vời về cách xử lý lỗi trong R trong cuốn sách Advanced-R của Hadley Wickham và những gì sau đây là phần giới thiệu rất cơ bản về withCallingHandlers()
và withRestarts()
càng ít từ càng tốt:
Giả sử một lập trình viên cấp thấp viết một hàm để tính giá trị tuyệt đối. Anh ấy không chắc cách tính toán nó, nhưng biết cách tính lỗi và siêng năng truyền đạt câu nói ngây thơ của mình:
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)
}
Một lập trình viên trung cấp cũng viết một hàm để tính giá trị tuyệt đối, sử dụng low_level_ABS
hàm không đầy đủ một cách đáng tiếc . Anh ta biết rằng mã cấp thấp tạo ra negative_value
lỗi khi giá trị của x
là âm và đề xuất giải pháp cho vấn đề, bằng cách thiết lập một mã restart
cho phép người dùng mid_level_ABS
kiểm soát cách mid_level_ABS
khôi phục (hoặc không) từ negative_value
lỗi.
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)
}
Cuối cùng, một lập trình viên cấp cao sử dụng mid_level_ABS
hàm để tính toán giá trị tuyệt đối và thiết lập một trình xử lý điều kiện để yêu cầu
mid_level_ABS
khôi phục negative_value
lỗi bằng cách sử dụng trình xử lý khởi động lại.
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)
}
Điểm mấu chốt của tất cả điều này là bằng cách sử dụng withRestarts()
và withCallingHandlers()
, hàm
high_level_ABS
có thể cho biết mid_level_ABS
cách khôi phục các lỗi do low_level_ABS
lỗi gây ra mà không ngừng thực hiện
mid_level_ABS
, đây là điều bạn không thể làm với 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
Trong thực tế, low_level_ABS
đại diện cho một hàm mid_level_ABS
gọi rất nhiều (thậm chí có thể hàng triệu lần), trong đó phương pháp xử lý lỗi chính xác có thể khác nhau tùy theo tình huống và việc lựa chọn cách xử lý các lỗi cụ thể được để cho các hàm cấp cao hơn ( high_level_ABS
).
Chức năng khởi động lại rất quan trọng trong R được kế thừa từ Lisp. Sẽ rất hữu ích nếu bạn muốn gọi một số hàm trong thân vòng lặp và bạn chỉ muốn chương trình tiếp tục nếu lệnh gọi hàm bị sập. Hãy thử mã này:
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(){})