中断/退出脚本

use*_*829 73 r exit break

我有一个程序可以进行一些数据分析,并且只有几百行.

在程序的早期,我想做一些质量控制,如果没有足够的数据,我希望程序终止并返回到R控制台.否则,我希望其余的代码执行.

我已经尝试了break,browser并且quit它们都没有停止执行程序的其余部分(并且quit停止执行以及完全退出R,这不是我想要发生的事情).我的最后一招是创建如下if-else声明:

 if(n < 500){}
 else{*insert rest of program here*}
Run Code Online (Sandbox Code Playgroud)

但这似乎是糟糕的编码实践.我错过了什么吗?

Mic*_*ick 56

stopifnot()如果希望程序产生错误,可以使用该函数:

foo <- function(x) {
    stopifnot(x > 500)
    # rest of program
}
Run Code Online (Sandbox Code Playgroud)

  • `stopifnot`很方便,但使用`if(x <500){stop("'x':n <500"中没有足够的观察结果)可能是首选.此外,如果这是批处理作业的事情,处理问题*而不*抛出错误是有用的. (20认同)
  • @ stackoverflowuser2010他不想`退出'(见问题!)我甚至不认为`stop`的'stop`是最好的办法来处理这个问题.`stop`抛出一个错误,整个脚本就会中止.虽然`stopifnot`(或`stop`)似乎是答案OP最喜欢的,写一个函数完全退出,没有错误,是在更大范围内的情况下,更有利.为大数据分析工作编写了大量长时间运行的脚本,没有什么比抛出错误而不是处理问题并且干净地返回的函数更令人烦恼.但显然我不知道我在说什么...... (9认同)
  • 不要试图混淆OP.他想要的是quit()或stop(),而不是stopifnot(). (4认同)

Tho*_*mas 12

反转你的if-else结构:

if(n >= 500) {
  # do stuff
}
# no need for else
Run Code Online (Sandbox Code Playgroud)

  • 很简单,我想这可能是我能做的最好的,谢谢 (2认同)

joc*_*hen 10

不漂亮,但这里是一种exit()在R中实现命令的方法,对我有用.

exit <- function() {
  .Internal(.invokeRestart(list(NULL, NULL), NULL))
}

print("this is the last message")
exit()
print("you should not see this")
Run Code Online (Sandbox Code Playgroud)

只是轻度测试,但是当我运行它时,我看到this is the last message然后脚本中止而没有任何错误消息.

  • 我让它与 `exit &lt;- function() { invokeRestart("abort") }` 一起使用 (3认同)

Rei*_*son 7

编辑:似乎OP正在运行一个长脚本,在这种情况下,只需要在质量控制之后包装脚本的一部分

if (n >= 500) {

.... long running code here

}
Run Code Online (Sandbox Code Playgroud)

如果突破某个函数,您可能只需要return()显式或隐式.

例如,显式双返回

foo <- function(x) {
  if(x < 10) {
    return(NA)
  } else {
    xx <- seq_len(x)
    xx <- cumsum(xx)
  }
  xx ## return(xx) is implied here
}

> foo(5)
[1] 0
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55
Run Code Online (Sandbox Code Playgroud)

通过return()暗示,我的意思是最后一行就好像你已经完成了return(xx),但是稍微高效一点就不用了return().

有些人认为使用多种退货方式不好; 在长函数中,跟踪函数退出的位置可能变得困难或容易出错.因此,另一种方法是使用单个返回点,但使用该if () else ()子句更改返回对象.这样的修改foo()就可以了

foo <- function(x) {
  ## out is NA or cumsum(xx) depending on x
  out <- if(x < 10) {
    NA
  } else {
    xx <- seq_len(x)
    cumsum(xx)
  }
  out ## return(out) is implied here
}

> foo(5)
[1] NA
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55
Run Code Online (Sandbox Code Playgroud)


use*_*103 7

这是一个老问题,但还没有一个干净的解决方案。这可能没有回答这个具体问题,但那些寻找“如何优雅地退出 R 脚本”答案的人可能会在这里找到答案。R 开发人员似乎忘记实现 exit() 函数。无论如何,我发现的技巧是:

continue <- TRUE

tryCatch({
     # You do something here that needs to exit gracefully without error.
     ...

     # We now say bye-bye         
     stop("exit")

}, error = function(e) {
    if (e$message != "exit") {
        # Your error message goes here. E.g.
        stop(e)
    }

    continue <<-FALSE
})

if (continue) {
     # Your code continues here
     ...
}

cat("done.\n")
Run Code Online (Sandbox Code Playgroud)

基本上,您使用标志来指示指定代码块是否继续。然后,您使用该stop()函数将自定义消息传递给函数的错误处理程序tryCatch()。如果错误处理程序收到您要正常退出的消息,那么它只会忽略该错误并将继续标志设置为FALSE


net*_*ink 5

也许您只是想在某个时候停止执行长脚本。即。就像您想用C或Python硬编码一个exit()一样。

print("this is the last message")
stop()
print("you should not see this")
Run Code Online (Sandbox Code Playgroud)

  • 对于此代码,我收到错误消息 `Error in eval(expr, envir, enclos) :`。 (2认同)
  • 是的,执行的确停止了。碰巧的是,如果将stop()替换为exit()或please.stop.now(),脚本也会停止(当然,错误消息也有所不同)。 (2认同)
  • @jochen 在 `stop()` 命令中添加带引号的短语可以帮助区分此“错误”与其他消息。例如:“stop(“此处插入手动中断”)”可能比单独的“stop()”提供更多信息。 (2认同)