How to Check Data type of a Variable in R

When it comes to checking the data type of a variable, it depends on what specific thing you are looking for in a variable, because you have many options to choose from. Each option tells you a different but important story.

There are four main core functions to check data types in R:

  1. typeof(): It returns the underlying storage type. It can be useful to understand low-level storage.
  2. class(): It returns an object’s class (S3 / S4), which dictates how functions will interact with it.
  3. mode(): It is similar to typeof() but less precise.
  4. storage.mode(): It uses older terminology such as, “double” instead of “numeric”. It is synonymous with the typeof() function.

Check Data type of a Variable in R

By checking the type, we won’t pass a string to a numeric algorithm.

Let’s take a simple code example:

vec <- 19:21

typeof(vec)
# [1] "integer"

class(vec)
# [1] "integer"

mode(vec)
# [1] "numeric"

storage.mode(vec)
# [1] "integer"

As you can see, only the mode() method returns less precise output, which is “numeric” instead of an “integer.”

Type Predicates: is.*() Functions

If you are working with an Atomic vector, there is an efficient way to check its data type.

For example, R’s simplest containers hold one of six basic types:

  1. For logical, use is.logical() method that returns a boolean value (TRUE or FALSE). If it finds a logical value, it returns TRUE, else FALSE.
  2. For integer checking, use the is.integer() method. It returns a boolean value (TRUE or FALSE). If it finds an integer value, it returns TRUE, else FALSE. It also returns FALSE for factors or dates.
  3. For double, use is.double() method. If it finds a double (float) value, it returns TRUE, otherwise FALSE.
  4. For complex, use is.complex() method. If it finds a complex value, it returns TRUE, otherwise FALSE.
  5. For character, use is.character() method. If it finds a character value, it returns TRUE, otherwise FALSE.
  6. For raw, use is.raw() method. If it finds a raw value, it returns TRUE, otherwise FALSE.
# --- Logical ---
logical_var <- TRUE

typeof(logical_var)
# [1] "logical"

is.logical(logical_var)
# [1] TRUE

# --- Integer ---
integer_var <- 123L

typeof(integer_var)
# [1] "integer"

is.integer(integer_var)
# [1] TRUE

is.numeric(integer_var) # Integers are also numeric
# [1] TRUE

# --- Double ---
double_var <- 3.14159

typeof(double_var)
# [1] "double"

is.double(double_var)
# [1] TRUE

is.numeric(double_var)
# [1] TRUE

double_var2 <- 100 # Default is double

typeof(double_var2)
# [1] "double"

is.double(double_var2)
# [1] TRUE

is.integer(double_var2) # Check if it's integer (False)
# [1] FALSE

# --- Complex ---
complex_var <- 2 + 3i

typeof(complex_var)
# [1] "complex"

is.complex(complex_var)
# [1] TRUE

is.numeric(complex_var) # Complex are not numeric
# [1] FALSE

# --- Character ---
character_var <- "Hello R!"

typeof(character_var)
# [1] "character"

is.character(character_var)
# [1] TRUE

# --- Raw ---
raw_var <- as.raw(48) # ASCII for '0'

typeof(raw_var)
# [1] "raw"

is.raw(raw_var)
# [1] TRUE

raw_var2 <- charToRaw("A") # Hex for 'A'

typeof(raw_var2)
# [1] "raw"

is.raw(raw_var2)
# [1] TRUE

There are other functions in these predicates that we will discuss later in this article.

Factors

By default, factors are stored internally as integers, but if you use is.integer(), it returns FALSE.

fact <- factor(c("k", "b"))

is.integer(fact)
# [1] FALSE

typeof(fact)
# [1] "integer"

Now, if you check its class, it will return a factor like this:

fact <- factor(c("k", "b"))

class(fact)
# [1] "factor"

To check if an input object is a factor, always use the is.factor(x) or inherits(x, “factor”).

fact <- factor(c("k", "b"))


is.factor(fact)
# [1] TRUE

Dates

Dates are stored as a double, but it has a class of “Date”. So, if you use is.numeric() function on it, it returns FALSE.

dt <- Sys.Date()

class(dt)
# [1] "Date"

typeof(dt)
# [1] "double" (days since 1970-01-01)

Lists, Data Frames, Matrices & Arrays

To check for a type list, always use the is.list() method.

main_list <- list(a = 1, b = "z", c = Sys.Date())

typeof(main_list)
# "list"

is.list(main_list)
# TRUE

To check for a type data frame, always use the is.data.frame() method. It has a class called “data.frame“.

df <- data.frame(x = 1:3, y = c("a", "b", "c"))

class(df)
# [1] "data.frame"

is.data.frame(df)
# [1] TRUE

typeof(df)
# [1] "list"

To check a Matrix / Array, you should use the is.matrix() / is.array() methods.

mat <- matrix(1:6, nrow = 2)

is.matrix(mat)
# [1] TRUE

is.array(mat)
# [1] TRUE

typeof(mat)
# [1] "integer"

class(mat)
# [1] "matrix" "array"

dim(mat)
# [1] 2 3

NA and NULL Types

You can interpret NA as missing values. NA can be logical, integer (NA_integer_), or double (NA_real_).

typeof(NA)
# [1] "logical"

typeof(NA_integer_)
# [1] "integer"

typeof(NA_real_)
# [1] "double"

typeof(NA_character_)
# [1] "character"

If you check a type for a NULL value, the typeof() function will return NULL.

typeof(NULL)

# [1] NULL

You can also use the is.null() function to check if an input value is NULL.

is.null(NULL)

# [1] TRUE

That’s all!

Leave a Comment