【问题标题】:Aborting execution of code in R(-Studio)中止在 R(-Studio) 中执行代码
【发布时间】:2015-07-27 10:17:43
【问题描述】:

我使用 RStudio 在 R 中编写代码。通常我通过选择它并按下 Ctrl + Enter 来提交更大的代码块。现在,当发生错误时(例如无法建立与数据库的连接),我想中止执行后续代码。

我试过stop(),当所有代码都在一行时,它可以工作:

# 21 is not shown
42; stop("error"); 21;

但是当代码跨越多行时,代码仍然会被计算:

# Here 21 is shown
42
stop("error")
21

在提交较大的代码块时是否有中止代码执行的方法?

【问题讨论】:

  • 放入大括号{}
  • @DavidArenburg 你应该把它写下来作为答案——它会得到我的投票!
  • @NickKennedy OK 已添加,但不确定如何正确表述。

标签: r rstudio abort


【解决方案1】:

您可以将代码包裹在{}(大括号)之间,因为它们几乎等同于您的; 链。

{
  42
  stop("error")
  21
}
## Error: error

这是来自文档的一个很好的插图,带有类似界面的功能。

do <- get("{")
do(x <- 3, y <- 2*x-3, 6-x-y)
## [1] 0
x <- 3; y <- 2*x-3; 6-x-y
## [1] 0

【讨论】:

  • 正如承诺的那样,我确实赞成您的回答;然后我意识到,仅仅用花括号括起来并不会打印每个语句的结果,这可能是 OP 想要的,并且为此编写一个函数有点超出了评论的范围 - 希望你不介意我发布了一个替代答案。
  • 不幸的是,这对我没有帮助。有时我想单步执行代码,有时我想一次运行更大的块。当逐行单步执行代码时(忘记不跳过左大括号),只有在到达右大括号时才会执行代码。
  • 好的,试试这个然后support.rstudio.com/hc/en-us/articles/…
【解决方案2】:

@DavidArenburg 的回答无疑是最直接的方法。但是,从您的问题中不清楚您是否想保留在运行时打印每个语句的值的行为,这是在 RStudio 中使用 Ctrl-Enter 时通常发生的情况。如果您确实想这样做,那么您的选择是:

  1. 将要输出的每个语句包装在print

例如

{
  print(42)
  stop("error")
  print(21)
}

#[1] 42
# Error: error
  1. 使用自定义函数来实现:

例如

block <- function(expr) {
  expr <- substitute(expr)
  for (i in seq(expr)[-1]) {
    y <- withVisible(eval(expr[[i]], parent.frame()))
    if (y$visible && i != length(expr)) print(y$value)
  }
  y$value
}

block({
  42
  stop("error")
  21
})

#[1] 42
# Error in eval(expr, envir, enclos) : error

请注意,在所有情况下,在您完成块之前,您的任何语句都不会真正执行。

对于重要的代码块,与标准执行相比,执行速度的差异可以忽略不计。

例如

microbenchmark::microbenchmark(block = block({
  a <- 1:1e6
  b <- rnorm(1e6)
  sum(a + b)
}), curly = {
  a <- 1:1e6
  b <- rnorm(1e6)
  sum(a + b)
})

#Unit: milliseconds
#  expr      min       lq     mean   median       uq      max neval
# block 108.7961 130.2517 169.4891 176.8425 197.4749 299.4014   100
# curly 109.9183 134.3076 171.9430 174.7121 194.5748 292.5958   100

【讨论】:

  • 这是一个不错的功能,但我怀疑 OP 是否真的想要打印结果,而不是在该块中运行代码,直到出现 stop。在那种情况下,这个函数可能会很慢。看看他们怎么说。
  • @DavidArenburg 谢谢。同意他们可能只想要阻止结果。我修改了代码以更接近命令的标准运行。只有在正常情况下才会打印输出(即不会像赋值一样不可见地返回),在调用环境中进行赋值并且整个函数的输出是最后一条语句的结果。我还对其进行了基准测试——总的来说,我的代码成本只是非平凡代码运行时间的一小部分。对于像 OP 这样的简单示例,显然它增加了相当大的开销。
猜你喜欢
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 2020-04-18
  • 1970-01-01
相关资源
最近更新 更多