Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting `immediate.` to `TRUE` with condition object in R?

Tags:

exception

r

I am trying to signal a custom condition in R using a condition object. However, it seems that I cannot set the immediate. argument to TRUE, nor can I alter any other argument to the stop, warning, etc functions. Is there a way to use condition objects but still retain the other arguments of stop, warning, and message ?

MWE:

Warning in perhaps the "usual" way works as expected, meaning that the warnings occur at each iteration. This is what I desire.

# 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]

In contrast, when using a condition object below, the warnings are collected and then we're told that there are 20 of them at the end:

Attempt 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)

Attempt 2 -- Setting the argument manually

 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)

Attempt 3 -- Deleting the immediate.=T argument from the cond object, and retrying (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)

Is there a way to use condition objects but still retain the other arguments of stop, warning, and message ?

like image 325
John Avatar asked Nov 06 '22 05:11

John


1 Answers

Okay so I have found a workaround/solution that gets the job done, although it is somewhat inelegant. In any case, the solution that works consists of:

  1. Wrapping the warning in a tryCatch block
  2. Capture the warning condition object
  3. Modify the captured object from (2) as needed
  4. Re-warn using the modified object from (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]
like image 177
John Avatar answered Nov 11 '22 06:11

John