33

有什么方法可以无错误地停止 R 程序吗?

例如,我有一个很大的来源,定义了几个函数,之后有一些函数调用。碰巧我编辑了一些函数,并希望在 R 环境中更新函数定义,但实际上并没有调用它们。

我定义了一个变量justUpdate,当它TRUE想要在函数定义之后停止程序时。

ReadInput <- function(...) ...
Analyze <- function(...) ...
WriteOutput <- function(...) ...

if (justUpdate)
    stop()
# main body
x <- ReadInput()
y <- Analyze(x)
WriteOutput(y)

我已经调用stop()了函数,但问题是它会打印一条错误消息。

ctrl+c是另一种选择,但我想在特定行中停止源。

q()or的问题quit()在于它终止了 R 会话,但我希望 R 会话仍然打开。

正如@JoshuaUlrich 建议的那样browser(),可以是另一种选择,但仍然不完美,因为源在新环境中终止(即 R 提示符将更改为Browser[1]>而不是>)。我们仍然可以按Q退出它,但我正在寻找直接的方法。

另一种选择是使用if (! justUpdate) { main body },但它正在清除问题,而不是解决问题。

有没有更好的选择?

4

11 回答 11

24

我在这里找到了一个相当巧妙的解决方案。诀窍是在调用之前关闭所有错误消息stop()。该功能on.exit()用于确保之后再次打开错误消息。该函数如下所示:

stop_quietly <- function() {
  opt <- options(show.error.messages = FALSE)
  on.exit(options(opt))
  stop()
}

第一行关闭错误消息并将旧设置存储到变量opt中。在此行之后,发生的任何错误都不会输出消息,因此也stop()不会导致打印任何消息。

根据 R 帮助,

on.exit记录作为其参数给出的表达式需要在当前函数退出时执行。

当前函数是,它在被调用stop_quietly()时退出。stop()所以程序做的最后一件事是 call options(opt),它将设置show.error.messages为它在被调用之前所拥有的值stop_quietly()(大概,但不一定,TRUE)。

于 2017-03-22T07:29:14.357 回答
14

这里的邮件列表中有一个很好的解决方案,它定义了一个stopQuietly基本上隐藏函数显示的错误的stop函数:

stopQuietly <- function(...) {
  blankMsg <- sprintf("\r%s\r", paste(rep(" ", getOption("width")-1L), collapse=" "));
  stop(simpleError(blankMsg));
} # stopQuietly()

> stopQuietly()
于 2015-11-25T12:01:44.410 回答
9

我有一个类似的问题,根据@VangelisTasoulas 的回答,我得到了一个简单的解决方案。
在函数内部,我必须检查数据库是否已更新。如果不是,则停止执行。

r=readline(prompt="Is DB updated?(y/n)")
Is DB updated?(y/n)n
if(r != 'y') stop('\r Update DB')
Update DB

只需放入\r消息的开头,覆盖Error:消息。

于 2017-06-12T21:10:33.373 回答
7

您正在寻找功能browser

于 2013-01-22T22:53:23.753 回答
5

您可以使用以下解决方案来停止 R 程序而不会出错:

if (justUpdate)
    return(cat(".. Your Message .. "))
于 2018-08-24T19:57:00.013 回答
1

只是return在你想退出该功能的那一行:

f <- function(x, dry=F) { 
   message("hi1")
   if (dry) return(x)
   message("hi2")
   x <- 2*x 
}
y1 <- f(2) # = 4 hi1 hi2
y2 <- f(2, dry=T) # = 2 hi1
于 2019-11-20T15:31:48.217 回答
0

我发现编写脚本并使用source(). 在脚本中,将退出语句作为一种特殊的错误类编写,atryCatch()可以将其作为消息接收并发送回:

exit <- function(..., .cl = NULL) {
  # Use to capture acceptable stop
  cond <- structure(
    list(.makeMessage(...), .cl),
    class = c("exitError", "error", "condition"),
    names = c("message", "call")
  )

  stop(cond)
}

foo <- function() {
  exit("quit here")
  1
}

tryCatch(
  # rather than foo(), you might use source(filename)
  foo(),
  exitError = function(e) message(e$message)
)
#> quit here

reprex 包于 2022-01-24 创建(v2.0.1)

于 2022-01-24T14:02:18.207 回答
0

除了 Stibu 于 17 年 3 月 22 日 7:29 的回答之外,如果您想要将消息作为 stop() 的一部分写入,则不会写入此消息。

我觉得奇怪的是必须使用以下两行意思 on.exit(options(options(show....))) 不起作用。

opt <- options(show.error.messages = F)
on.exit(options(opt))
于 2020-11-24T11:27:15.853 回答
0

我忘记了这个问题的答案,需要查找并登陆这里......你在你的问题中发布了答案的提示......

ctrl+c 是另一种选择,但我想在特定行中停止源。

发出错误、警告或消息的信号

rlang::inform("Updated Only")
rlang::interrupt()

于 2021-12-25T22:29:07.517 回答
-1

为什么不直接使用 if () {} else {}?这只是几个字符...

f1 <- function(){}
f2 <- function(){}

if (justUpdate) {
} else {
# main body 
}

甚至

f1 <- function(){}
f2 <- function(){}

if (!justUpdate) {
# main body 
}
于 2019-11-22T07:36:51.820 回答
-1

下面的代码对我的工作停止了,没有错误消息。

opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
break
于 2020-12-15T06:08:08.090 回答