How do you check for a scalar in R?

I think is.atomic suits your needs.

For why is.vector is probably incompatible, see, e.g.:

is.atomic(list(1))
# [1] FALSE

is.vector(list(1))
# [1] TRUE

On your objects:

is.scalar <- function(x) is.atomic(x) && length(x) == 1L

is.scalar(doub)
# [1] TRUE

is.scalar(intg)
# [1] TRUE

is.scalar(c(doub, intg))
# [1] FALSE

Building on the answer by @MichaelChirico, there are a couple of other things that is.scalar() should check for.

Firstly, complex numbers are not usually regarded as scalars (although I think this usage may vary between disciplines).

comp <- 2+3i
is.scalar <- function(x) is.atomic(x) && length(x) == 1L
is.scalar(comp)
# TRUE

so we should also check for complex numbers. The simple, but naive, way to do this is to use is.complex

is.scalar <- function(x) is.atomic(x) && length(x) == 1L && !is.complex(x) 
is.scalar(comp)
# FALSE

Unfortunately, this is not quite right, because is.complex just tests whether the class is "complex". But real numbers can have class=complex if their imaginary component is zero.

is.complex(2+0i)
# [1] TRUE

So to test for real numbers we are better off to check that the imaginary component is zero using Im(x)==0. So, this leads us to a test for scalars that look like this

is.scalar <- function(x) is.atomic(x) && length(x) == 1L && Im(x)==0

More trivially, characters ought also be eliminated

is.scalar("x")
# TRUE
is.scalar <- function(x) is.atomic(x) && length(x) == 1L && !is.character(x) && Im(x)==0
is.scalar("x")
# FALSE

Note that we test for is.character(x) before Im(x)==0 so that lazy evaluation ensures that the function never tries to find the imaginary component of a character, which would throw an error.

Tags:

R