Search code examples
rprintfcharacterassertthat

R: error when printing character() in assert_that message


I would like to assert some expressions involving certain variable that is potentially evaluated to character(). I would like to print an assertation message showing the value of the variable which can be character().

assertthat::assert_that(<expr containing variable [x]>, msg = sprintf("Test for x failed on value %s" , x))

## Variable [x] is a character variable that can be character() or other conventional characters like `"a"`, `"b"` or ``"c"``.

Below is a simplified example to show the error I obtained when the variable is evaluated to character():

assertthat::assert_that(FALSE, msg = sprintf("%s", character()))

gives me error

## > Error in stop(assertError(attr(res, "msg"))) : bad error message

However the sprintf itself works well

sprintf("%s", character())
## character(0)

sprintf("%s", character()) %>% typeof
## [1] "character"

What I have tried:

  • Wrap %s with backticks assert_that(FALSE, msg = sprintf("`%s`", character()))
  • Load the assertthat package first with library(assertthat) then call assert_that(...)
  • Assign first character() to a variable and call that variable in assert_that which is actually more similar to my real life use case
    v <- character()
    assert_that(FALSE, msg = sprintf("`%s`", v))
    
  • Assign the return value of sprintf call to a variable and then feed it into the call of assert_that
    v <- character()
    errmsg <- sprintf("`%s`", v)
    assert_that(FALSE, msg = errmsg)
    

All gave same error. It seems something inside assert_that affects.

What would be the reason of the error and how to fix it?


Solution

  • I think the problem here is that your sprintf statements results in a character with length 0:

    length(sprintf("%s", character()))
    #> [1] 0
    

    This means there is not really a message for assert_that to print. So you have to ensure the length of the sprintf output has a length of 1:

    require(assertthat)
    #> Loading required package: assertthat
    assert_that(F, msg=character())
    #> Error in stop(assertError(attr(res, "msg"))) : bad error message
    assert_that(F, msg=letters[1:2])
    #> Error in stop(assertError(attr(res, "msg"))) : bad error message
    assert_that(F, msg=letters[1])
    #> Error: a