繁体   English   中英

在 RStudio/Interactive R 会话中出现错误时停止执行

[英]Make execution stop on error in RStudio / Interactive R session

在 RStudio 中执行代码块时,发生错误时实际上不会停止执行。 例如,如果我在打开的编辑器中有以下代码:

x <- 'test'
stopifnot(is.numeric(x))
print('hello world')

并运行它(使用命令返回或单击“运行”按钮),它会打印错误,然后继续执行打印语句。

有没有办法将 RStudio 配置为不继续错误? 即让它停在上面的第 2 行而不继续打印语句?

编辑:刚刚意识到如果我使用 command-R 在标准 R GUI 中发送代码块也会发生这种情况。

解决此问题的一种方法是配置 R 'error'选项以在遇到错误时运行自定义函数。

一个示例错误处理函数可以使用Sys.sleep暂停 R 的执行并等待用户输入(例如,通过按 ctrl-C 来中断正在运行的函数,或在我的 Mac 上的 R-Studio 中退出)。

通常,R 将继续执行任何后续命令。 但是,我们可以通过定义一个函数来防止这种情况发生,该函数将“吃掉”所有这些,这样它们就不会运行。 为了使这个更流畅,我们可以在每个“吃掉”行之后输出一个“光标向上”字符序列,这会在下一个输出时擦除它们中的每一个,这样未运行的行就不会弄乱终端/安慰。

示例代码:

# Define our error-handling pause function:

pause=function(){
    on.exit(eat_input())
    cat("Paused: press ctrl-C (or Escape key in Rstudio) to continue\n")
    cat("(any subsequent code will be ignored)\n")
    Sys.sleep(Inf)
}

# Define our 'eat_input' function to prevent output of subsequent, not-run input:

eat_input=function(){
    cat("\033[1A")
    while((x=readline())!='')cat("\033[1A")
}

# Set the 'error' option to execute our pause function:

options(error=pause)

试试看:

print("Before the error")

# an error: we want to stop after this
xxx

# some more input: we don't want this to be run or to appear in the console
print("After the error")

要关闭此行为,只需将错误选项重新设置为NULL

options(error=NULL)

当您选择一个部分并按Ctrl + Enter时,我认为没有办法阻止RStudio运行所有行。 Rstudio只是一个接一个地运行。 即使在函数内部调用了stopifnot() ,仍然会对该函数调用之后的所有行进行求值。

如果你的目标只是在出现问题时被告知,那么在很多代码运行之前,你可以定义一个类似于stopifnot()的函数,如果出现错误,它将进入无限循环。 然后,您可以按Esc或RStudio中的停止按钮来中断程序。 像这样的东西:

waitifnot <- function(cond) {
  if (!cond) {
    message(deparse(substitute(cond)), " is not TRUE")  
    while (TRUE) {}
  }
}

现在,您可以使用此函数运行示例代码:

x <- 'test'
waitifnot(is.numeric(x))
print('hello world')

正如所料, hello world永远不会被打印出来。 您将收到一条错误消息,告诉您出现了问题,然后程序将一直等到您手动中止它。

除了交互模式之外,这在任何情况下都不会很好。 为避免出现不愉快的情况,如果未在交互模式下使用,您还可以让函数做出不同的反应,例如:

waitifnot <- function(cond) {
  if (!cond) {
    msg <- paste(deparse(substitute(cond)), "is not TRUE")
    if (interactive()) {
      message(msg)
      while (TRUE) {}
    } else {
      stop(msg)
    }
  }
}

只有在交互模式下运行时,此功能才会进入无限循环。 否则,它将通过调用stop()简单地中止执行。 我已经通过Ctrl + Enter或RStudio(无限循环)中的Source按钮以及Bash命令行上的Rscript (程序中止)检查了这是否正常工作。

正如@lmo 所提到的,您只需要点击按钮Source而不是 select all + Run 事实上,您甚至不需要保存脚本文件就可以点击“ Source按钮。

但问题确实在于Source将始终运行整个脚本。 所以如果你真的只想在脚本中运行一个块,这对你没有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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