Пропуск медленных задач в цикле в R

Я пытаюсь запустить симуляцию в R, где я создаю целую кучу филогенетических деревьев. Моделирование дерева представляет собой небольшую проблему, потому что время его выполнения сильно варьируется, иногда 0,005 секунды, а иногда минуты. Я хочу избежать медленных деревьев, поэтому я пытаюсь использовать evalWithTimeout, чтобы пропустить их. Пока что у меня проблемы, потому что я не могу убить медленные задачи, не прерывая цикл. Моя проблема похожа на этот вопрос, но решение этого вопроса мне не помогло.

library(TreeSim)
library(R.utils)
for (i in 1:100){
  tryCatch(
    expr = {
      evalWithTimeout(sim.rateshift.taxa(10,1,c(0.5,2),c(0.5,0),
                                         c(1,1),c(0,0.5),complete=F),
      timeout=0.005)
    }, 
    TimeoutException = function(ex) cat("Timeout. Skipping.\n")
  )
  print(i)
}

Это то, что я до сих пор. Я хотел бы, чтобы он продолжал печатать "i" независимо от того, превышает ли время симуляция ограничение, но в настоящее время он выдает мне ошибки "достигнуто ограничение по времени процессора" и останавливается.

2 ответа

Решение

Использование https://www.rdocumentation.org/packages/R.utils/versions/2.5.0/topics/withTimeout в качестве источника. Вот тестовый модуль, который работает как положено.

foo = function() {
    print("Tic");
    x <- ceiling(runif(1) * 100)+1;
    for (kk in 1:x) {
        print(kk);
        Sys.sleep(runif(1));
    }
    print("Tac");
}

bar = function() { 
  for (i in 1:100) { 
    tryCatch({
      res <- withTimeout({
        foo();
     }, timeout=1.08);
    }, TimeoutException=function(ex) {
        cat("Timeout. Skipping.\n");
       }); 
    print(i); 
   } 
}

Таким образом, вопрос в том, есть ли ошибка, возникающая при прерывании sim.rateshift.taxa, которая не перехватывается, используйте error как упоминается, чтобы поймать это, но использовать TimeoutException, чтобы пропустить правильные тайм-ауты

Существует также проблема с установкой слишком низкого лимита времени:

https://github.com/mhahsler/arules/issues/22

Вы можете просто использовать setTimeLimit себя и убедитесь, что transient установлен на TRUE, так что у вас есть более тонкий контроль.

Вот пример, взятый из http://blog.revolutionanalytics.com/2014/10/r-in-production-controlling-runtime.html

system.time(Sys.sleep(5))

##user system elapsed 
## 0.000 0.000 5.005

system.time(local({
  setTimeLimit(elapsed = 1, transient = TRUE)
  Sys.sleep(5)
}))

## Error in Sys.sleep(5): reached elapsed time limit

## Timing stopped at: 0 0 5.006

Попробуй это:

library(TreeSim)
library(R.utils)
for (i in 1:100){
  tryCatch(
    expr = {
      evalWithTimeout(sim.rateshift.taxa(10,1,c(0.5,2),c(0.5,0),
                                         c(1,1),c(0,0.5),complete=F), timeout=0.005)
    }, error = function(ex) cat("Timeout. Skipping.\n"))
  print(i)
}

Как упоминает @AhmedMasud в комментарии, функция выдает другую ошибку. Итак, используя error = ... ловит любую другую проблему, а также.

Другие вопросы по тегам