Is.integer () behavior on reassignments
Let's create an integer vector and assign an integer value to its 1st element and re-assign it to non-integer.
> int = integer(0)
> int[1]
> NA
> is.integer(int)
[1] TRUE
# assign int[1] to an integer
> int[1] = 1L
> is.integer(int)
[1] TRUE
# Now, re-assign to a non-integer
> int[1] = 1
> is.integer(int)
[1] FALSE # as expected
Now let's do the same, but in reverse order, that is, first assign a non-integer number, and then assign an integer again.
# try again assigning to a non-integer first
> int = integer(0)
> int[1] = 1
> is.integer(int)
[1] FALSE
# Now, assigning to integer
> int[1] = 1L
> is.integer(int)
[1] FALSE # why?
Does the type of the last assessment match the previous assignment?
source to share
I would formulate the behavior you see a little differently:
x <- 1:2
> storage.mode(x)
[1] "integer"
> x <- x + 0.5
> storage.mode(x)
[1] "double"
> x
[1] 1.5 2.5
> storage.mode(x) <- "integer"
> x
[1] 1 2
In general, asking R to convert objects back to an integer can lead to information loss. So when an assignment forces you to convert a double, there is no return unless you explicitly ask for it (which is good).
In the particular example you chose, it was assumed that there was only one value, but R really does not have a scalar type, so everything has to think in terms of vectors. This means that many R operations need to be aware of the possible effects that all things will have on integer vectors of values.
source to share
Does the type of the last assessment match the previous assignment?
Not. int[1] = 1
implicitly coerces int
from integer to numeric because you assigned a numeric value to an element of an integer vector.
In the example below, R will not force coercion num
from a number to an integer, because that could result in data loss ... and always checking if a numeric vector from an integer can be safely distinguished is inefficient.
num <- numeric(0)
num[1] <- 1L
source to share
If you wanted to is.integer
return what you expected, you would need to do some action that would force this numeric (== 8 byte type) to an integer (4 byte). Assigning an integer value to a numeric vector would not require coercion. The same thing happens if you assign a boolean empty integer:
> int = integer(0)
> int[1]
[1] NA
> int[1] <- FALSE
> int
[1] 0
source to share
From ?is.integer
,
is.integer
returnsTRUE
eitherFALSE
depending on whether its argument is an integertype
or not, unless it is a factor when it returnsFALSE
.
Putting this on a test, we can see why is.integer
returnsFALSE
> int <- integer(0)
> int[1] <- 1
> typeof(int)
# [1] "double"
> int[1] <- 1L
> typeof(int)
# [1] "double"
source to share