Reputation: 51
In R, is.integer(1)
returns FALSE and class(1)
returns "numeric" while is.integer(1:1)
returns TRUE and class(1:1)
returns "integer". Why does not is.integer(1)
return TRUE?
Comparing the printed values to the output of class() or typeof() leads to counter intuitive results. E.g.
x1=seq(from=1, to=5, by=1)
x2=1:5
x1
[1] 1 2 3 4 5
x2
[1] 1 2 3 4 5
class(x1)
[1] "numeric"
class(x2)
[1] "integer"
To determine if x1 contains integer values I need to use all(as.integer(x1)==x1)
. Is there an easier way?
class()
can return an array, e.g. an ordered factor. Shouldn't class(1)
return c("numeric", "integer")?
Upvotes: 5
Views: 2703
Reputation: 99331
Hopefully this helps clear things up a bit. Your example doesn't necessarily
tell the whole truth. In fact, the vector type returned from seq
depends
on which arguments you use. Here's a look at the example set-ups from
?seq
.
seqList <- list(
fromto = seq(from = 1, to = 5),
fromtoby = seq(from = 1, to = 5, by = 1),
fromtolengthout = seq(from = 1, to = 5, length.out = 5),
alongwith = seq(along.with = 5),
from = seq(from = 1),
lengthout = seq(length.out = 5),
binary = 1:5
)
With the result, we can see that when we use the by
argument (as you did),
the result is not of integer type. The type of result is changed to numeric once argument checking occurs (I think, correct me if I'm wrong).
str(seqList)
# List of 7
# $ fromto : int [1:5] 1 2 3 4 5
# $ fromtoby : num [1:5] 1 2 3 4 5
# $ fromtolengthout: num [1:5] 1 2 3 4 5
# $ alongwith : int 1
# $ from : int 1
# $ lengthout : int [1:5] 1 2 3 4 5
# $ binary : int [1:5] 1 2 3 4 5
seq
is a generic function that dispatches to different methods based on the supplied arguments. It's all explained in ?seq
. It's worth a read. There are also seq.int
, seq_len
, and seq_along
which are also different from seq
. Now in reference to your question
To determine if x1 contains integer values I need to use
all(as.integer(x1)==x1)
. Is there an easier way?
That check might cause some issues, as factors are also integers
f <- factor(letters[1:5])
x <- 1:5
f == x
# [1] FALSE FALSE FALSE FALSE FALSE
as.integer(f) == x
# [1] TRUE TRUE TRUE TRUE TRUE
I'd go with inherits
or typeof
. The first returns a logical, which would work nicely in if
statements. And typeof
returns a character string of the vector type.
look <- function(x) {
c(class = class(x), typeof = typeof(x),
mode = mode(x), inherits = inherits(x, "integer"))
}
noquote(do.call(rbind, lapply(seqList, look)))
# class typeof mode inherits
# fromto integer integer numeric TRUE
# fromtoby numeric double numeric FALSE
# fromtolengthout numeric double numeric FALSE
# alongwith integer integer numeric TRUE
# from integer integer numeric TRUE
# lengthout integer integer numeric TRUE
# binary integer integer numeric TRUE
Reading the help files is very informative. I'm definitely not an expert on this stuff, so if I've gotten anything wrong here, please let me know. Here's something more to stimulate the curiosity:
is.integer(1)
# [1] FALSE
is.integer(1L)
# [1] TRUE
Upvotes: 4