首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在RStudio /交互式R会话中出现错误时停止执行

在RStudio /交互式R会话中出现错误时停止执行
EN

Stack Overflow用户
提问于 2017-02-16 01:29:20
回答 3查看 5.4K关注 0票数 19

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

代码语言:javascript
运行
复制
x <- 'test'
stopifnot(is.numeric(x))
print('hello world')

并运行它(使用命令-return或单击" run“按钮),它会打印错误,但随后继续并执行print语句。

有没有一种方法可以将RStudio配置为不跳过错误?也就是说,让它停在上面的第2行,而不是继续打印语句?

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-16 03:39:33

我不认为有一种方法可以阻止RStudio运行所有行,当您选择一个节并按Ctrl+Enter键时。Rstudio只是一行接一行地运行。即使在函数内部调用stopifnot(),该函数调用之后的所有行仍将被计算。

如果你的目标仅仅是在出现错误时得到通知,在大量代码白运行之前,也许你可以定义一个类似于stopifnot()的函数,如果出现错误,它将进入无穷无尽的循环。然后,您可以按Esc或RStudio中的停止按钮来中断程序。如下所示:

代码语言:javascript
运行
复制
waitifnot <- function(cond) {
  if (!cond) {
    message(deparse(substitute(cond)), " is not TRUE")  
    while (TRUE) {}
  }
}

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

代码语言:javascript
运行
复制
x <- 'test'
waitifnot(is.numeric(x))
print('hello world')

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

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

代码语言:javascript
运行
复制
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中的源按钮(死循环)和Bash命令行上的Rscript (中止程序)是否能正常工作。

票数 2
EN

Stack Overflow用户

发布于 2021-08-10 13:24:29

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

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

正常情况下,R将继续执行任何后续命令。然而,我们可以通过定义一个函数来防止这种情况发生,该函数将“吃掉”所有这些代码,这样它们就不会运行。为了让这个过程更流畅,我们可以在每个“吃”行之后输出一个“cursor up”字符序列,这会在下一行被输出时清除掉它们,这样没有运行的行就不会弄乱终端/控制台。

示例代码:

代码语言:javascript
运行
复制
# 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)

试试看:

代码语言:javascript
运行
复制
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")

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

代码语言:javascript
运行
复制
options(error=NULL)
票数 4
EN

Stack Overflow用户

发布于 2020-08-07 03:04:54

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

但真正的问题是,Source将始终运行整个脚本。因此,如果您真的只想在脚本中运行一个块,这对您没有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42256291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档