Henrik Bengtsson
2020-Aug-14 21:05 UTC
[Rd] Bug in stats:::`[.formula`: (~ NULL)[2] gives Error ... missing value where TRUE/FALSE needed
Hi, it looks like:> stats:::`[.formula`function (x, i) { ans <- NextMethod("[") if (length(ans) == 0L || as.character(ans[[1L]])[1L] == "~") { class(ans) <- "formula" environment(ans) <- environment(x) } ans } <bytecode: 0x556688d87cc0> <environment: namespace:stats> doesn't like to extract NULL components on either the LHS or RHS. For example, with> (~ NULL)[2]Error in if (length(ans) == 0L || as.character(ans[[1L]])[1L] == "~") { : missing value where TRUE/FALSE needed this despite:> str(as.list(~ NULL))List of 2 $ : symbol ~ $ : NULL - attr(*, "class")= chr "formula" - attr(*, ".Environment")=<environment: R_GlobalEnv>> length(~ NULL)[1] 2> (~ NULL)[[2]]NULL Other examples are:> (NULL ~ .)[2]Error in if (length(ans) == 0L || as.character(ans[[1L]])[1L] == "~") { : missing value where TRUE/FALSE needed> (NULL ~ NULL)[3]Error in if (length(ans) == 0L || as.character(ans[[1L]])[1L] == "~") { : missing value where TRUE/FALSE needed TROUBLESHOOTING: The reason is that ans[[1L]] becomes NULL;> trace(stats:::`[.formula`, tracer = quote(utils::str(as.list(ans))), at = 3L)Tracing function "[.formula" in package "stats (not-exported)" [1] "[.formula"> (~ NULL)[2]Tracing `[.formula`((~NULL), 2) step 3 List of 1 $ : NULL Error in if (length(ans) == 0L || as.character(ans[[1L]])[1L] == "~") { : missing value where TRUE/FALSE needed which causes 'as.character(ans[[1L]])[1L] == "~"' to resolve to NA. PATCH: A minimal backward compatible fix would be: `[.formula` <- function(x,i) { ans <- NextMethod("[") ## as.character gives a vector. if(length(ans) == 0L || (is.null(ans[[1L]]) && i <= length(x)) || as.character(ans[[1L]])[1L] == "~") { class(ans) <- "formula" environment(ans) <- environment(x) } ans } A better fix would probably be to also detect out of range as in: `[.formula` <- function(x,i) { if (i > length(x)) stop(gettext("index out of range")) ans <- NextMethod("[") ## as.character gives a vector. if(length(ans) == 0L || is.null(ans[[1L]]) || as.character(ans[[1L]])[1L] == "~") { class(ans) <- "formula" environment(ans) <- environment(x) } ans } /Henrik
Maybe Matching Threads
- Rcpp too good to be true?
- Using 'dimname names' in aperm() and apply()
- a fast table() for the 1D case
- PATCH: Avoiding extra copies (NAMED bumped) with source(..., print.eval=FALSE) ...and with print.eval=TRUE?
- stepAICc function (based on MASS:::stepAIC.default)