gpt4 book ai didi

r - 在 tryCatch 中处理多个可能的错误

转载 作者:行者123 更新时间:2023-12-04 17:57:28 26 4
gpt4 key购买 nike

我试图在 for 循环中处理两个可能的错误,它调用 stplanr::dist_google与 API 交互。我知道错误,所以我想在它们发生时采取具体的行动。

如果我尝试仅处理可能的错误之一,它会起作用:

data(cents, package = "stplanr")
data(flow, package = "stplanr")

od <- stplanr::od2odf(flow=flow, zones=cents)

uma_linha <- data.frame(from_addresses=NA, to_addresses=NA, distances=NA,
duration=NA, currency=NA, fare=NA)
output <- data.frame()

for (linha in 1:nrow(od)) {
o <- od[linha, 3:4]
d <- od[linha, 5:6]
output <- tryCatch(
{
rbind(output, stplanr::dist_google(from = o, to = d,
mode = 'walking'))
},
error = function(na) {
message("Erro: No results for this request (e.g. due to lack of support for this mode between the from and to locations)")
message(na)
output <- rbind(output, uma_linha)
}
)
}

我需要获得超过 2500 次观察的结果。然后,自动化使用两个api。我试图将另一条消息和一个小技巧作为一个 Action 。当我调用循环时,我反复收到两条错误消息。
n <- 1
apis <- c("api01", "api02", "api03")

for (linha in 1:nrow(od)) {
o <- od[linha, 3:4]
d <- od[linha, 5:6]
output <- tryCatch(
{
rbind(output, stplanr::dist_google(from = o, to = d,
mode = 'walking',
google_api = apis[n]))
},
error = function(na) {
message("Erro: No results for this request (e.g. due to lack of support for this mode between the from and to locations)")
message(na)
output <- rbind(output, uma_linha)
},
error = function(quota) {
message("Erro: You have exceeded your daily request quota for this API.")
message(quota)
n <- n + 1
return(n)
}
)
}

我对 tryCatch 感到困惑。我究竟做错了什么?

非常感谢您的帮助。

编辑

在 Martin 的清晰解释之后,我尝试将所有内容都放在一个函数中。它不起作用。

如果错误是:
No results for this request (e.g. due to lack of support for this mode between the from and to locations)

然后该函数将继续并返回一个空对象。当配额结束并且错误是:
You have exceeded your daily request quota for this API.

它递归地返回错误,而不是执行 n <- n + 1并继续循环:
asha_dists <- function(fluxo, zonas, api) {
zonas <- as(st_transform(zonas, 4326), "Spatial")
od <- stplanr::od2odf(flow = fluxo, zones = zonas)
uma_linha <- data.frame(from_addresses=NA, to_addresses=NA, distances=NA,
duration=NA, currency=NA, fare=NA)
n <- 1
output <- data.frame()
for (linha in 1:nrow(od)) {
o <- od[linha, 3:4]
d <- od[linha, 5:6]
output <- tryCatch(
{
rbind(output, stplanr::dist_google(from = o, to = d,
mode = 'walking', google_api = api[n]))
},
custom_error = function(e) {
err <- conditionMessage(e)
message("found custom_error: ", err)
output <- rbind(output, uma_linha)
},
error = function(e) {
err <- conditionMessage(e)
message("found an error: ", err)
n <- n + 1
}
)
}
return(output)
}

Sent this request: https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=-23.5678377804732,-46.5708261676873&destinations=-23.5706647015703,-46.5755950203842&mode=walking&key=AIzaSyBRPrAjSE_pRMWSq_XlO4BFwGD63j_gB4U
found an error: You have exceeded your daily request quota for this API.
Sent this request: https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=-23.5665596480444,-46.5682308348154&destinations=-23.5706647015703,-46.5755950203842&mode=walking&key=AIzaSyBRPrAjSE_pRMWSq_XlO4BFwGD63j_gB4U
found an error: You have exceeded your daily request quota for this API.

我只是被困住了。

最佳答案

有两种方法可以捕获错误类型,这取决于错误是如何生成的。这是一个产生错误的函数

f <- function(type) {
switch(
type,
a = stop("oops a: type 1 error"),
b = stop("oops b: type 2 error"),
c = {
err <- simpleError("oop 2: custom error class")
class(err) <- c("custom_error", class(err))
stop(err)
}
)
}

type是“a”或“b”,则该函数生成标准错误条件,但具有不同的条件消息(“oops a: ...”和“oops b: ...”)。如 type是“c”,那么错误有一个特定的类“custom_error”,它扩展了标准错误的(S3)类。
> f("a")
Error in f("a") : oops a: type 1 error
> f("b")
Error in f("b") : oops b: type 2 error
> f("c")
Error: oop 2: custom error class

这是一个捕获错误的函数。
g <- function(type) {
tryCatch({
f(type)
}, custom_error = function(e) {
err <- conditionMessage(e)
message("found custom_error: ", err)
}, error = function(e) {
err <- conditionMessage(e)
if (startsWith(err, "oops a")) {
message("found type 'a' error: ", err)
} else if (startsWith(err, "oops b")) {
message("found type 'b' error: ", err)
} else {
message("generic error: ", err)
}
})
}

tryCatch 的处理程序参数按照它们在参数列表中出现的顺序进行测试,如果它们与错误的类相匹配,则会对其进行评估。 "a"或 "b"类型的错误具有相同的类,因此被相同的处理程序捕获;区分它们的唯一选择是“刮取”错误消息,查看条件(错误)消息以确定正在处理的错误类型(希望该包不会复杂到包含错误消息翻译,例如基础 R 可以,因为通常不可能以稳健的方式刮除翻译错误......)
> g("a")
found type 'a' error: oops a: type 1 error
> g("b")
found type 'b' error: oops b: type 2 error

另一方面,处理程序可以捕获类型“c”,因为它有自己的类。所以...
> g("c")
found custom_error: oop 2: custom error class

实际上可以沿着错误处理程序或调用堆栈传递错误
h <- function(type) {
tryCatch({
f(type)
}, custom_error = function(e) {
err <- conditionMessage(e)
message("found custom_error: ", err)
stop(e)
}, error = function(e) {
err <- conditionMessage(e)
message("found an error: ", err)
stop(e)
})
}


> h("c")
found custom_error: oop 2: custom error class
found an error: oop 2: custom error class
Error: oop 2: custom error class

很少有软件包能够真正使用生成自定义错误的功能,因此您可能会坚持尝试抓取您确实看到的错误。对于您的情况,您似乎必须抓取,所以
output <- tryCatch({
rbind(
output,
stplanr::dist_google(
from = o, to = d, mode = 'walking', google_api = api[n]
)
)
}, error = function(e) {
err <- conditionMessage(e)
if (startsWith("No results for this request", err) {
warning(err) # warn instead of error
n <<- n + 1 # '<<-' to update n _outside_ this function
rbind(output, uma_linha) # empty output as result
} else if (startsWith("You have exceeded your daily", err) {
stop(e) # signal the original error
} else {
stop(e) # no error that we know how to handle, signal
}
})

关于r - 在 tryCatch 中处理多个可能的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51109954/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com