Written and maintained by CASRAI Editorial Board
Last updated
R has six basic (“atomic”) vector types: logical, integer, double (real), complex, character and raw. Everything else, including lists, factors and data frames, is built from them. The part that trips researchers up is not the list of types but the difference between what typeof(), class() and mode() report, and the coercion rule that silently turns a numeric column into text. This guide covers those two things first, then the practical steps.
What it is used for in research
Knowing an object’s type tells you which operations are valid on it and what happens when values of different types meet. In a research workflow this matters at three points: when data are read in (a column that should be numeric arrives as character), when vectors are combined (the result takes the “highest” type present), and when missing values are handled (NA in a logical vector behaves differently from NaN in a numeric one). The guide to loading data into R and the guide to data frames in R show where these types appear in practice.
The six atomic types, plus the rest
The R Language Definition states that “R has six basic (‘atomic’) vector types: logical, integer, real, complex, character (in C aka ‘string’) and raw.” Lists are also vectors, and the term atomic vector is used “where it is necessary to exclude lists.”
| Type (as returned by typeof) | What the manuals say |
|---|---|
| logical | The elements of a logical vector can have the values TRUE, FALSE, and NA, where NA stands for not available (An Introduction to R, section 2.4). |
| integer | Stored as 32-bit integers, with a range of about plus or minus 2 x 10^9 (?integer help page). |
| double | The “real” type of the Language Definition; typeof reports it as “double” (?typeof help page). |
| complex | One of the six atomic types (R Language Definition). |
| character | One of the six atomic types, called a string in C (R Language Definition). |
| raw | One of the six atomic types (R Language Definition). |
| list | A vector that is not atomic (R Language Definition). |
Beyond vectors, typeof can also return values such as NULL, closure, environment, language, expression and S4. Factors are created with factor() (An Introduction to R, section 4.1) and are a class layered on top of these types rather than a seventh atomic type.
Install or access (official source only)
The R manuals quoted on this page are published on CRAN, the Comprehensive R Archive Network, at cran.r-project.org/doc/manuals/r-release/. The manuals are for R version 4.6.1 (2026-06-24). The base functions used below (typeof, class, mode, c, is.integer, is.na) are part of base R, so no extra package is needed.
Step-by-step: check the type of a value
- Create a value, for example
x <- c(1, 2, 3). - Ask for its internal type with
typeof(x). The ?typeof help page lists “double” among the values it can return for numbers. - Ask for its class with
class(x). The Language Definition notes that “R has an elaborate class system, principally controlled via the class attribute”, so class can differ from the underlying type, as it does for factors. - Ask for its mode and length with
mode(x)andlength(x). An Introduction to R says these “can be used to find out the mode and length of any defined structure.” - Test a specific type with the
is.functions, for exampleis.integer(x). Be careful with this one, covered next.
Output and how to read it
Why is.integer(1) is FALSE
The ?integer help page flags this directly with the example is.integer(1) # is FALSE ! and notes that is.integer(x) does not test whether x contains whole numbers; it tests whether x is stored as the integer type. A number typed without any special syntax is stored as a real (double) value, so a check for the integer type returns FALSE even when the value looks whole.
How large can an integer be?
Integer vectors use 32-bit integers, with a range of about plus or minus 2 x 10^9. The same page states that real values larger in modulus than the largest integer are coerced to NA when converted to integer, so a conversion of a very large count to integer gives a missing value rather than an error.
What is the difference between typeof, class and mode?
typeof returns the type of an R object, as listed in the table above. class reflects the class system, which the Language Definition says is “principally controlled via the class attribute.” mode and length are the functions An Introduction to R points to for inspecting any structure, and it states that “Vectors must have their values all of the same mode.”
NA versus NaN
An Introduction to R states that “is.na(xx) is TRUE both for NA and NaN values.” So is.na() cannot tell you which of the two you have; both are flagged as missing or undefined.
Troubleshooting
Why did my numeric vector turn into text?
Because c() coerces everything to a single type. The ?c help page gives the rule: “The output type is determined from the highest type of the components in the hierarchy NULL < raw < logical < integer < double < complex < character < list < expression.” Combining numbers with one character value, as in c(1, "a"), therefore returns a character vector, because character sits above double in that hierarchy. The same ordering explains why logical values combined with numbers become numbers.
Why do I get NA after converting a large number to integer?
The value exceeds the 32-bit integer range described above. Keep it as a double, or store it as text if it is an identifier rather than a quantity.
Why does a data frame column have an unexpected type?
Vectors must hold values of one mode, so a column that mixes numbers and text cannot stay numeric. Check the column with typeof(), then see the data import guide. The cbind in R guide shows how combining columns of different types behaves, and the map in R guide covers applying a function across elements whose types differ.
Free alternatives
All of the checks above use base R functions that ship with R itself. This table lists them with the statement each manual makes.
| Base R function | Documented behaviour |
|---|---|
| typeof() | Returns a character string naming the type of an R object (?typeof). |
| mode() and length() | Find out the mode and length of any defined structure (An Introduction to R, 3.1). |
| is.integer() | Tests for the integer type, not for whole-number values (?integer). |
| is.na() | TRUE for both NA and NaN (An Introduction to R, 2.5). |
| c() | Coerces to the highest type in the hierarchy (?c). |
| factor() | Creates a factor (An Introduction to R, 4.1). |
FAQ
How many data types does R have?
Six atomic vector types: logical, integer, double, complex, character and raw. Lists are vectors too, and typeof can additionally report types such as NULL, closure and environment.
What is the difference between integer and numeric in R?
Integer is a storage type using 32-bit integers. A plain number such as 1 is stored as a double, which is why is.integer(1) is FALSE.
What happens when I mix types in one vector?
The result takes the highest type in the order NULL, raw, logical, integer, double, complex, character, list, expression.
Is a factor a data type?
A factor is created with factor() and is a class built on the basic types, not one of the six atomic vector types.
Sources (official docs)
- R Core Team, R Language Definition (R-lang), version 4.6.1: https://cran.r-project.org/doc/manuals/r-release/R-lang.html. Checked 2026-10-29.
- R Core Team, An Introduction to R (R-intro), version 4.6.1: https://cran.r-project.org/doc/manuals/r-release/R-intro.html. Checked 2026-10-29.
- R documentation, ?c: https://stat.ethz.ch/R-manual/R-devel/library/base/html/c.html. Checked 2026-10-29.
- R documentation, ?integer: https://stat.ethz.ch/R-manual/R-devel/library/base/html/integer.html. Checked 2026-10-29.
- R documentation, ?typeof: https://stat.ethz.ch/R-manual/R-devel/library/base/html/typeof.html. Checked 2026-10-29.







