Ограничение времени обработки функции в цикле R for
Я хочу применить функцию ("foo" для этого объяснения), чтобы преобразовать вектор данных в другое значение. Эта функция принимает данные в качестве входных данных и должна отправлять формы на веб-страницы. Иногда это происходит быстро, а иногда - долго. Я хотел бы запустить цикл for (или эквивалентную функцию apply) таким образом, чтобы пропустить элементы, которые занимают слишком много времени. Я попытался ограничить время выполнения цикла перед переходом к следующим 5 секундам, используя следующее:
pb <- txtProgressBar(min = 1, max = 100, style = 3)
storage <- matrix(nrow = sample.length, ncol = 2)
for(i in 1:100){
s <- Sys.time()
storage[i,] <- try(foo(data.vec[i]), TRUE)
if (Sys.time() - s >5) {next}
# update progress bar
setTxtProgressBar(pb, i)
}
close(pb)
Я думаю, что я не должен понимать, как применять условие 'next' в цикле for. искал, чтобы найти более ясное объяснение, но не получал никакой удачи здесь.
2 ответа
evalWithTimeout()
из пакета R.utils
, совместно с tryCatch()
, может обеспечить более чистое решение.
Например:
require(R.utils)
for(i in 1:5) {
tryCatch(
expr = {
evalWithTimeout({Sys.sleep(i); cat(i, "\n")},
timeout = 3.1)
},
TimeoutException = function(ex) cat("Timeout. Skipping.\n")
)
}
# 1
# 2
# 3
# Timeout. Skipping.
# Timeout. Skipping.
В искусственном примере выше:
Первый аргумент
evalWithTimeout()
содержит код для оценки в каждом цикле.timeout
аргументevalWithTimeout()
устанавливает ограничение по времени в секундах.TimeoutException
аргументtryCatch()
принимает функцию, которая должна быть выполнена, когда время итерации цикла истекло.
Я работаю над тем, чтобы заставить цикл работать в foreach с %dopar%, поэтому запуск сообщения об ошибке вызвал у меня головную боль, так как это разорвет цикл.
Я каждый раз создаю переменную skip, и когда происходит тайм-аут, цикл переходит к следующей итерации. Надеемся, что вы избежите «остановки» или «перерыва» при использовании с партнерскими функциями.
for(i in 1:5) {
res=NULL
skip=FALSE
tryCatch(
{res= withTimeout({Sys.sleep(i);
cat(i, "\n")}, timeout = 3.1,
onTimeout='error')
},
TimeoutException = function(ex){skip <<-
TRUE})
if(skip){next}
}