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?

+3


source to share


4 answers


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.

+7


source


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

      

+3


source


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

      

+2


source


From ?is.integer

,

is.integer

returns TRUE

either FALSE

depending on whether its argument is an integer type

or not, unless it is a factor when it returns FALSE

.

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"

      

+1


source







All Articles