如何在R中停止/结束/终止脚本?

45
我写了一个脚本,如果提供的数据不正确,应该停止执行。然而,尽管stop会产生错误消息,但脚本仍然继续执行。以下是一个最简示例:
if (TRUE) {stop("End of script?")} #It should stop here
print("Script did NOT end!") # but it doesn't, because this line is printed!

控制台输出:

> if (TRUE) {stop("End of script?")}
Error: End of script?
> print("Script did NOT end!")
[1] "Script did NOT end!"
>

这并不奇怪,因为从?stop可以看出:
停止当前表达式的执行并执行错误操作。
所以它只结束当前表达式,而不是整个脚本。我在这里发现你可以将{}包裹整个脚本(或者将其放入函数中),但这似乎更像是一个变通方法而不是解决方案。当然,捕获错误并自行处理是良好的编程实践(例如mra68评论中的链接),但我仍然想知道是否可以停止R脚本。
我还尝试了returnbreak,但这仅适用于函数或循环。我搜索了其他可能的关键字,如“halt”和“end”,但没有找到合适的。我感觉有点愚蠢,因为这似乎是一个非常基本的问题。 那么,是否有命令可以使我的R脚本终止/停止/结束,并产生致命错误? 我在Windows 8上运行R 3.2.3,但在MAC-OSX上使用R 3.0.1时也遇到了同样的问题。
> sessionInfo()
R version 3.2.3 (2015-12-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

locale:
[1] LC_COLLATE=Dutch_Netherlands.1252  LC_CTYPE=Dutch_Netherlands.1252    LC_MONETARY=Dutch_Netherlands.1252
[4] LC_NUMERIC=C                       LC_TIME=Dutch_Netherlands.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] tools_3.2.3

在Mac-OS上测试,使用sessionInfo()函数。

R version 3.0.1 (2013-05-16)
Platform: x86_64-apple-darwin10.8.0 (64-bit)

locale:
[1] nl_NL.UTF-8/nl_NL.UTF-8/nl_NL.UTF-8/C/nl_NL.UTF-8/nl_NL.UTF-8

2
我建议您将想要运行的任何代码放入一个函数中,然后调用该函数。然后您可以使用 stop 命令,在那一点上终止函数。在 R 中,函数语句也可用于声明方法,就像其他编程语言一样,这可能会产生误导。 - vanao veneri
1
在我的系统上(R版本3.2.3,操作系统Windows 7),"stop" 命令停止了脚本。如果你查看 "stop" 命令的源代码,你会发现它的行为取决于一些内部函数,而这些函数可能与机器有关。 - mra68
这个链接可能会有用:http://adv-r.had.co.nz/beyond-exception-handling.html。但如果是的话,那么这个问题绝对不是基础问题。 - mra68
@RHA:是的,我确定。如果你尝试使用 q() 会发生什么?在我的系统上,它会中断整个 R 会话。也许把你的 sessionInfo() 放到问题里面。 - mra68
@RHA:我也可以使用 if (TRUE) {.Internal(.dfltStop("End of script?", TRUE))} 来停止脚本。也许你有一个不同的内部函数 .dfltStop - mra68
显示剩余9条评论
4个回答

24

也许现在有点晚了,但我最近遇到了同样的问题,并发现对我来说最简单的解决方案是使用:

quit(save="ask")

?quit可以看出:

save必须是"no"、"yes"、"ask"或"default"之一。在第一种情况下,工作区不会被保存,在第二种情况下它会被保存,在第三种情况下用户会被提示并且可以选择不退出。默认情况下,在交互式使用中会询问,但可以通过命令行参数进行覆盖(必须在非交互使用中提供)。

当弹出消息框时,您可以通过点击“取消”来决定不退出 R。

希望这可以帮到您!


1
永远不会太晚得到答案。这确实是另一种解决方法。'quit' 旨在退出整个会话,但正如您所描述的那样,它可以被取消。 - RHA
2
在RStudio中,这个命令会终止R,并提示你重新启动会话。 - robertspierre
不确定自回答以来Rstudio是否有所改变,但用户不再有取消退出的选项;调用quit始终会导致会话终止。这使得本答案在您仅想要停止脚本执行时(例如调试时)变得不那么有用。 - RHA

18

据我所知,没有一种有效的单个命令能在所有平台/版本上真正停止脚本。有几种处理方法:

将其放入函数或花括号中:

{
if (TRUE) {stop("The value is TRUE, so the script must end here")}

print("Script did NOT end!")
}

或者评估错误并处理它,就像在if else结构中一样:

if (TRUE) {stop("The value is TRUE, so the script must end here")    
  } else { #continue the script
print("Script did NOT end!")   
  }

或者(修改):另一种可能性是从单独的“主”R脚本中调用脚本,使用source("MyScript.R")。然后,脚本将终止。然而,这会抑制除控制台错误之外的所有输出。

或者,对于更复杂的操作,可以使用tryCatch(),如此处所示


3
请注意,在RStudio中,这个标签是:

stop("Error message")

调用实际上会在打印错误消息后停止脚本的执行。


3
不,脚本会继续执行。 - Luke

2
非常简单:调用一个未声明的函数。
condition <- TRUE
if (condition) {
  print('Reason for stopping')
  UNDECLARED()
}

脚本将停止并显示以下消息:

[1] "Reason for stopping"
Error in UNDECLARED() : could not find function "UNDECLARED"

3
这似乎不是最干净的做事方式。为什么不使用quit()stopstopifnot等呢? - Roman Luštrik
它不起作用,脚本仍在运行。 - Luke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接