简体   繁体   中英

Manually interrupt a loop in R and continue below

I have a loop in R that does very time-consuming calculations. I can set a max-iterations variable to make sure it doesn't continue forever (eg if it is not converging), and gracefully return meaningful output.

But sometimes the iterations could be stopped way before max-iterations is reached. Anyone who has an idea about how to give the user the opportunity to interrupt a loop - without having to wait for user input after each iteration? Preferably something that works in RStudio on all platforms.

I cannot find a function that listens for keystrokes or similar user input without halting until something is done by the user. Another solution would be to listen for a global variable change. But I don't see how I could change such a variable value when a script is running.

The best idea I can come up with is to make another script that creates a file that the first script checks for the existence of, and then breaks if it is there. But that is indeed an ugly hack.

Inspired by Edo's reply, here is an example of what I want to do:

test.it<-function(t) {
  a <- 0
  for(i in 1:10){
    a <- a + 1
    Sys.sleep(t)
  }
  print(a)
}
test.it(1)

As you see, when I interrupt by hitting the read button in RStudio, I break out of the whole function, not just the loop.

Also inspired by Edo's response I discovered the withRestarts function, but I don't think it catches interrupts.

I tried to create a loop as you described it.

a <- 0

for(i in 1:10){
  
  a <- a + 1
  Sys.sleep(1)
  if(i == 5) break
  
}

print(a)

If you let it go till the end, a will be equal to 5, because of the break . If you stop it manually by clicking on the STOP SIGN on the Rstudio Console, you get a lower number. So it actually works as you would like.

If you want a better answer, you should post a reproducible example of your code.

EDIT

Based on the edit you posted... Try with this.

It's a trycatch solution that returns the last available a value

test_it <- function(t) {
  
  a <- 0
  
  tryCatch(
    for(i in 1:10){
      a <- a + 1
      message("I'm at ", i)
      Sys.sleep(t)
      if(i==5) break
    },
    interrupt = function(e){a}
  )
  
  a
}


test_it(1)

If you stop it by clicking the Stop Sign, it returns the last value a is equal to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM