无误地停止R程序

无误地停止R程序,r,debugging,R,Debugging,有没有办法停止一个R程序而不出错 例如,我有一个大的源代码,定义了几个函数,之后是对函数的一些调用。碰巧我编辑了一些函数,并希望在R环境中更新函数定义,但实际上并没有调用它们 我定义了一个变量justUpdate,当它为真时,我希望在函数定义之后立即停止程序 ReadInput <- function(...) ... Analyze <- function(...) ... WriteOutput <- function(...) ... if (justUpdate)

有没有办法停止一个R程序而不出错

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

我定义了一个变量justUpdate,当它为真时,我希望在函数定义之后立即停止程序

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

if (justUpdate)
    stop()
# main body
x <- ReadInput()
y <- Analyze(x)
WriteOutput(y)
我调用了stop函数,但问题是它打印了一条错误消息

ctrl+c是另一个选项,但我想在特定行中停止源代码

q或quit的问题是它终止了R会话,但我希望R会话仍然打开

正如@JoshuaUlrich建议的浏览器可以是另一种选择,但仍然不是完美的,因为源终止于一个新的环境,即R提示符将更改为browser[1]>而不是>。我们仍然可以按Q退出,但我正在寻找一个简单的方法

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


有更好的选择吗?

您正在寻找函数浏览器。

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

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

> stopQuietly()
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

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

stop_quietly <- function() {
  opt <- options(show.error.messages = FALSE)
  on.exit(options(opt))
  stop()
}
第一行关闭错误消息并将旧设置存储到变量opt。在此行之后,发生的任何错误都不会输出消息,因此,停止也不会导致打印任何消息

根据R的帮助

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


当前函数是stop_,在调用stop时退出。因此,程序所做的最后一件事是调用options option,它会将show.error.messages设置为它所拥有的值,在stop_悄无声息地被调用之前,它可能会被调用,但不一定是真的。

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

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

只需将\r放在消息的开头,即可覆盖消息中的错误。

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

if (justUpdate)
    return(cat(".. Your Message .. "))
只要在希望代码退出的地方退出即可。它悄然发生

只需在要退出函数的行中返回一些内容:

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

> stopQuietly()
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

为什么不使用if{}else{}呢?这只是几个角色

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

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

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

if (!justUpdate) {
# main body 
}

除了2017年3月22日7:29从Stibu回复外,如果您想在stop中写一条消息,则不写此消息

我感到奇怪的是,下面两行必须用来表示.exitoptionsoptionsshow。。。。不起作用

opt <- options(show.error.messages = F)
on.exit(options(opt))

以下代码为我停止工作,没有错误消息

opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
break

谢谢,浏览器是个不错的选择,但并不完美。当我将其放入源代码中时,程序从我想要的行成功停止,但是提示改为Browser[1]>而不是>,这意味着在新环境中。我想要与我的源代码正常完成的环境相同的环境在该提示符下键入Q关闭浏览器提示符并返回主提示符…@PaulHiemstra谢谢我更新了问题,你有什么更方便的想法吗?你想休息吗?你能详细说明你想做什么,为什么吗?这可以帮助我们帮助您。@joran我不想关闭所有错误消息。请将您的函数定义放在一个单独的文件中,或者更好的是,从您的程序中取出一个包,并在您更新函数后将其作为源文件;或2使用如果!只是更新{…}。我推荐1。你现在想要做的是用一种混乱的方式来组织你的代码。一些编程语言称之为库,另一些称之为模块,另一些称之为包,但在任何地方都是相同的想法:它应该只包含函数。要运行的代码应该只在主脚本中。这是编程101。“你尝试的其他任何东西都是愚蠢的,”阿里说,“是的,它叫返回,但在顶级不起作用。”。如果你想停止而不出错,你需要把所有的东西都封装在一个函数中。谢谢欢迎来到SO!这可能回答了问题,但简短的解释和上下文可以帮助每个人理解您的解决方案。break用于退出for和while循环。其余的答案在别人面前。