R Integers

R stores whole numbers as doubles by default, and only treats them as true integers when you mark them with the L suffix or convert them explicitly.

Marking a Number as an Integer

By default, typing 5 creates a double, R's standard numeric type. Appending the letter L, as in 5L, tells R to store the value as a true integer instead — the same type you'll see returned by functions like seq_len() or nrow().

Example

a <- 5L
class(a)
# "integer"

b <- 5
class(b)
# "numeric"

Converting Between Types

as.integer() converts a double, or a numeric-looking string, into an integer — truncating any decimal part rather than rounding it. as.double() (or the equivalent as.numeric()) converts an integer back into a double.

Example

as.integer(9.9)
# 9

as.integer("42")
# 42

as.double(7L)
# 7

Integer Overflow

R's integers are stored using 32 bits, so the largest whole number they can represent is stored in .Machine$integer.max — about 2.15 billion. Going one past that limit doesn't wrap around like some languages; it silently produces NA along with a warning.

Example

.Machine$integer.max
# 2147483647

big <- .Machine$integer.max + 1L
# Warning message:
# NAs produced by integer overflow

When to Reach for Integers

  • Sequences created by 1:10 or seq_len(n) are already stored as integers
  • Loop counters and vector indices are naturally whole numbers
  • Marking a value as an integer signals intent — this quantity should never have a fractional part
Note: is.integer(x) checks the storage type strictly: is.integer(5) is FALSE because 5 is a double, while is.integer(5L) is TRUE. If you just want to know whether something is any kind of number, use is.numeric(x) instead.