class()
class(x) The class() function in R is fundamental to the object’s class system. It retrieves or sets the class attribute of an object, which determines how generic functions dispatch methods.
Syntax
class(x)
class(x) <- value
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
x | any | , | An R object whose class to get or set |
Examples
Getting the class of an object
The class() function returns the class attribute of any R object as a character string. For atomic vectors without an explicit class attribute, R returns the implicit class based on the storage type: "numeric" for doubles, "integer" for integers, "character" for strings, and "logical" for booleans. More complex objects like data frames, matrices, and factors carry explicit class attributes that control how generic functions like print() and summary() dispatch.
# Vector class
x <- c(1, 2, 3)
class(x)
# [1] "numeric"
# Data frame class
df <- data.frame(a = 1:3, b = letters[1:3])
class(df)
# [1] "data.frame"
# Matrix class
m <- matrix(1:9, nrow = 3)
class(m)
# [1] "matrix" "array"
# Factor class
f <- factor(c("a", "b", "a"))
class(f)
# [1] "factor"
Checking class membership
Beyond inspecting an object’s class, you often need to test whether an object belongs to a specific class. The inherits() function checks if a given class name appears anywhere in the object’s class vector, making it more reliable than direct equality comparison. This matters for objects with multiple classes, where class(x) == "some_class" returns FALSE even when the object genuinely inherits from that class.
# Use inherits() to check for class membership
x <- data.frame(a = 1)
inherits(x, "data.frame")
# [1] TRUE
# Check multiple classes
class(x)
# [1] "data.frame" "list" "oldClass"
inherits(x, "list")
# [1] TRUE
Setting a class
You can assign a class to any R object using class(x) <- value. This is the standard way to create S3 classes: add a class attribute to an existing object like a list or vector, then define S3 methods such as print.myclass() and summary.myclass() that dispatch on that class name. The class attribute is just a character vector, so creating an S3 class requires no formal definition beyond choosing a name and writing the methods.
# Create a custom class
x <- 1:10
class(x) <- "myVector"
class(x)
# [1] "myVector"
# Add class to existing object
y <- list(a = 1, b = 2)
class(y) <- "customList"
print.myList <- function(x) {
cat("Custom list:\n")
print(unclass(x))
}
print(y)
Common patterns
S3 method dispatch
R uses the class to dispatch generic functions:
S3 method dispatch works by searching for functions named generic.class when a generic function like print() or summary() is called on an object. R concatenates the generic name with the class name using a dot, then looks for that function in the search path. If the object has multiple classes in its class vector, R tries each class in order until it finds a matching method, falling back to print.default() if no specific method exists. This dispatch mechanism is what makes classes useful beyond simple labelling.
# The print generic looks at class
print
# It dispatches to print.data.frame for data.frames
print.data.frame <- function(x, ...) {
# custom print behavior
}
# Same data, different class = different print
df <- data.frame(x = 1:3)
class(df) <- "myTable"
print(df) # uses print.myTable if defined
Class inspection workflow
When exploring unfamiliar objects, a systematic inspection workflow reveals both the object-oriented interface and the underlying storage. Call class() first to see which methods will dispatch, then use attributes() to list all attached metadata including names, dimensions, and row names. Finally, use inherits() for targeted class checks and str() or typeof() to understand the internal representation. This layered approach prevents surprises when generic functions behave unexpectedly on unfamiliar object types.
# Complete inspection of an object
obj <- mtcars
# 1. Get the class
class(obj)
# [1] "data.frame"
# 2. Get attributes
attributes(obj)
# 3. Check inheritance
inherits(obj, "data.frame") # TRUE
inherits(obj, "matrix") # FALSE
class() in practice
class() returns the class attribute of an object, which determines how generic functions (like print(), summary(), plot()) dispatch. Most objects have a single class: class(1.5) returns "numeric", class(TRUE) returns "logical". S3 classes can have multiple classes in a vector: class(tibble()) returns c("tbl_df", "tbl", "data.frame"), and method dispatch tries each class in order.
is() and inherits() test class membership for S4 and S3 objects respectively: inherits(df, "data.frame") returns TRUE for both data frames and tibbles, because tibbles inherit from data.frame. Using class(x) == "data.frame" would return FALSE for tibbles. In defensive code, prefer is.data.frame(x) or inherits(x, "data.frame") over exact class comparison.
Setting class: class(x) <- "my_class" adds an S3 class to any object. This is how S3 classes are created: add a class attribute and write print.my_class(), summary.my_class(), etc. methods. The class attribute is just a character vector — there is no formal class definition required for S3.
typeof() returns the underlying storage type (how the object is stored in memory): "double", "integer", "character", etc. class() returns the object-oriented class used for dispatch. They differ for most objects: class(1L) is "integer", and typeof(1L) is also "integer", but class(matrix(1:4, 2, 2)) is "matrix" "array" while typeof(matrix(1:4, 2, 2)) is "integer".
class() returns the class attribute, which controls S3 method dispatch. For vectors without an explicit class, R returns an implicit class: "integer", "numeric", "character", etc. inherits(x, "lm") tests whether x has "lm" in its class vector, which is more reliable than class(x) == "lm" for objects with multiple classes. oldClass() and class<-() get and set the class attribute directly.
class() returns the class attribute that drives S3 method dispatch. Primitive types like integers return implicit classes: class(1L) is "integer", class(1.0) is "numeric", class(TRUE) is "logical". These implicit classes are not stored as attributes — they are computed from the type.
Objects can have multiple classes, stored as a character vector: class(lm_obj) returns c("lm"), while class(glm_obj) returns c("glm", "lm"). Method dispatch tries each class in order and calls the first match.
inherits(x, "classname") tests whether "classname" appears anywhere in the class vector. It is more reliable than class(x) == "classname" which fails for multi-class objects. is(x, "classname") from the methods package does the same for S4 objects.
unclass(x) strips the class attribute, letting you inspect the underlying structure. attr(x, "class") <- "myclass" or class(x) <- "myclass" sets a custom class. Custom classes enable you to define print.myclass(), summary.myclass(), and other S3 generics.