使用 R 中的条件对象将 `immediate.` 设置为 `TRUE`?

Joh*_*ohn 5 r exception

我正在尝试使用条件对象在 R 中发出自定义条件信号。然而,似乎我不能设置immediate.参数TRUE,我也可以改变其他任何参数的stopwarning等功能。有没有办法使用条件对象,但仍保留的其他参数的方式stopwarningmessage

MWE:

警告可能以“通常”的方式按预期工作,这意味着在每次迭代时都会出现警告。这就是我的愿望。

# Works as expected
for(i in 1:20){warning("A warning", immediate.=T) ; Sys.sleep(.1)}
>Warning: A warning
>Warning: A warning
>Warning: A warning
>Warning: A warning
>Warning: A warning
... [truncated]
Run Code Online (Sandbox Code Playgroud)

相比之下,当使用下面的条件对象时,会收集警告,然后我们被告知最后有 20 个警告:

尝试 1

# Does not signal warning immediately 
cond = structure(list(message="A warning", call=NULL, immediate.=T), class=c("warning", "condition"))

for(i in 1:20){ warning(cond); Sys.sleep(.1) }
>There were 20 warnings (use warnings() to see them)
Run Code Online (Sandbox Code Playgroud)

尝试 2 -- 手动设置参数

 for(i in 1:20) {warning(cond, immediate.=T); Sys.sleep(.1)}
>additional arguments ignored in warning()
>additional arguments ignored in warning()
>...[truncated]
>There were 20 warnings (use warnings() to see them)
Run Code Online (Sandbox Code Playgroud)

尝试 3 --immediate.=Tcond对象中删除参数,然后重试 (2)

cond = structure(list(message="A warning", call=NULL), class=c("warning", "condition"))

for(i in 1:20) {warning(cond, immediate.=T); Sys.sleep(.1)}
>additional arguments ignored in warning()
>additional arguments ignored in warning()
>...[truncated]
>There were 20 warnings (use warnings() to see them)
Run Code Online (Sandbox Code Playgroud)

有没有办法使用条件对象,但仍保留的其他参数的方式stopwarningmessage

Joh*_*ohn 1

好吧,我找到了一个解决方法/解决方案来完成工作,尽管它有点不优雅。无论如何,有效的解决方案包括:

  1. 将警告包装在tryCatch块中
  2. 捕获警告条件对象
  3. 根据需要修改(2)中捕获的对象
  4. 使用 (3) 中修改后的对象重新发出警告
# Set immediate. to false, collects warnings as expected
my.call = "A call"

for(i in 1:20){

  tryCatch(warning("A warning", immediate.=F),
           warning = function(w){w$call <- my.call; warning(w)}
           )

  Sys.sleep(.1)
  
} 

>There were 20 warnings (use warnings() to see them)


# changing immediate. to true, warns at each iteration as desired
for(i in 1:20){

  tryCatch(warning("A warning", immediate.=T),
           warning = function(w){w$call <- my.call; warning(w)}
           )

  Sys.sleep(.1)
  
} 

>Warning in "A call" : A warning
>Warning in "A call" : A warning
>Warning in "A call" : A warning
>...[truncated]
Run Code Online (Sandbox Code Playgroud)