Is numeric() broken ?

I was trying to use the vctrs package and I come up with the following error message:

library(vctrs)
vec_assert(1L, numeric())
#> Error: `1L` must be a vector with type <double>.
#> Instead, it has type <integer>.

I am pretty sure that numeric can be either double or integer, then I did a little bit of digging:

class(1L) == class(integer())
#> [1] TRUE
class(1L) == class(numeric())
#> [1] FALSE
is.numeric(1L)
#> [1] TRUE

Is numeric() broken, or is it something that I don't understand?

I think the answer is that numeric is always a double precision floating point number, you can assign integer values to it, but they are represented internally as double precision floating point numbers.
vctrs gives you vec_ptype_common(1L,1) that you can use to find common compatible class.
In this case numeric/double as integers can be freely translated to those.

some notes from the purrr package's deprecated is_numeric function:

#'
#' Numeric is used in three different ways in base R:
#' * as an alias for double (as in [as.numeric()])
#' * to mean either integer or double (as in [mode()])
#' * for something representable as numeric (as in [as.numeric()])
#' This function tests for the second, which is often not what you want
#' so these functions are deprecated.
#'
#' @export
#' @keywords internal
is_numeric <- function(x) {
warning("Deprecated", call. = FALSE)
is_integer(x) || is_double(x)
}
2 Likes

Thanks for the answer, it is way more clear to me now.

typeof(double())
#> [1] "double"
typeof(numeric())
#> [1] "double"
typeof(integer())
#> [1] "integer"

So I guess base::is.numeric() checks whether is.double() or is.numeric(), while numeric() is just an alias for double(). Did I get this right?

yeah, and the great thing is , you can write your own function, that has an is_* type logic of your own devising ! :slight_smile:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.