The `$` Operator in R

Used to extract a single element from a list or “list-like” object, the $ operator is the bread-and-butter tool for working with data interactively.1

Summary

  • The $ operator follows the syntax x$name

    • x is the object containing the data of interest
    • name is the name of the corresponding element within x.
  • Use the $ operator to read (x$name), write (x$name <- y), or delete (x$name <- NULL) data from either a list or list-like object

  • The $ operator performs partial matching on the supplied name argument


What is $?

Everything in R is an object. And objects contain data. Extraction operators are functions that retrieve the data contained within objects. $ is an extraction operator.

Specifically, the $ operator extracts a single element from a list or “list-like” object. It is a bread-and-butter tool for working with data interactively.2

You can use it to select a column from a dataframe. More generally3, you can use it to select an element from a list. Even more generally, you can use it to select an element from a list-like object such as: a call, formula, or function.

Wait a minute. What are “list-like” objects?

Examples of list-like objects include: calls, functions, formulas, and environments - among many others. A list-like object is also sometimes called a recursive object. From the R Documentation(“R: Is an Object Atomic or Recursive?” n.d.):

Most types of objects are regarded as recursive. Exceptions are the atomic types, NULL, symbols (as given by as.name), S4 objects with slots, external pointers, and—rarely visible from R—weak references and byte code

What does $ do?

You can use the $ operator to read, write, or delete data from either a list or list-like object. In the following code examples, suppose you have an object named x, an element - within x - named name, and another object named y.

Read - To access the element named name in the object x do:

x$name

Write - To assign the object y to the element named name in the object x do:

x$name <- y

Delete - To delete the element named name in the object x do:

x$name <- NULL

Important!: If instead you want to assign the value NULL do:

x$name <- list(NULL)

How does $ work?

Syntax

The $ operator follows the syntax x$name4 - where x is the object containing the data of interest, and name is the name of the corresponding element within x.

# Names are case-sensitive: these two names are considered to be different.
iris$Species
iris$species 

Name Matching

The $ matches, or searches for, the supplied name argument among the object names of x (names(x)).

There are two kinds of matches: exact matches and partial matches. An exact match happens when name is identical to an object name. A partial match happens when name is a prefix5 of an object name.

With the $ operator, if the object does not have an exact match for name, but there is exactly one partial match, then the $ operator returns that match.

The following diagram summarizes the behavior of the $ operator in different scenarios.

name_matching_diagrams

This can all seem a bit abstract, so I’ll try to make it concrete. Let’s take a look at some examples.

Examples

For these examples, I’ll use the classic iris dataset that comes bundled with R. Also, for the sake of demonstration, let us only consider the first few rows of the dataset.

mini_iris <- head(iris) # Selects only the first 6 rows of iris

Note that mini_iris also has the following five names:

> names(mini_iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species" 
With Exact Matching

Recall that an exact match occurs when the supplied name is identical to an object name. Each of the examples below are instances of exact matches because the name argument for each expression is a name in mini_iris.

# Using symbols/names
> mini_iris$Sepal.Length
[1] 5.1 4.9 4.7 4.6 5.0 5.4

> mini_iris$Petal.Length
[1] 1.4 1.4 1.3 1.5 1.4 1.7


# Using a literal string
> mini_iris$"Petal.Length"
[1] 1.4 1.4 1.3 1.5 1.4 1.7
With Partial Matching

When there is exactly one match6, the $ operator simply returns the matching element.

Here, in the example below, you can see that iris$Spec has a single match (“Spec” only matches “Species”). Therefore the $ operator returns the element corresponding to the name “Species” (In effect, the original call of iris$Spec is translated to iris$Species).

> iris$Spec
  [1] setosa     setosa     setosa     setosa     setosa     setosa     setosa     

*Where there is **more than one match*,** the $ operator returns NULL.

For example, consider the input iris$Sepal. The supplied name, “Sepal”, matches two different object names: both “Sepal.Length” and “Sepal.Width”. In this instance, the $ operator returns NULL.

> iris$Sepal
NULL

Note!: Below observe that partial matching is performed for both literal strings and literal names.

> iris$Sepal.L # Calling the operator with a name
  [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 4.8 4.3 5.8 5.7 5.4 5.1 5.7 

> iris$"Sepal.W" # Calling the operator with a string
  [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 4.8 4.3 5.8 5.7 5.4 5.1 5.7 

Lastly, when there is no match the $ operator also returns NULL.

> mini_iris$apple
NULL

>mini_iris$"bar"
NULL

References

De Vries, Andrie, and Joris Meys. 2015. R for Dummies. 2nd edition. –For Dummies. Hoboken, New Jersey: John Wiley & Sons, Inc.
“R: Extract or Replace Parts of an Object.” n.d. Accessed June 26, 2022. https://stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html.
“R: Is an Object Atomic or Recursive?” n.d. Accessed June 28, 2022. https://stat.ethz.ch/R-manual/R-devel/library/base/html/is.recursive.html.
Wickham, Hadley. 2019. Advanced R. Second edition. Boca Raton: CRC Press/Taylor and Francis Group.

  1. Because when you’re working interactively, you’ll know for certain the name of the element that you want to extract (On the flip side, if you need dynamic (run-time) calculations use the [[ operator).↩︎

  2. Because when you’re working interactively, you’ll know for certain the name of the element that you want to extract (On the flip side, if you need dynamic (run-time) calculations use the [[ operator).↩︎

  3. Dataframes are actually a special instance of a list. That is, if x is a dataframe, then typeof(x) == "list"↩︎

  4. FYI, the $ operator is the only infix extraction operator - that is it goes in between it’s two arguments (Think of the algebraic operators (+ - * / ^) from Math class).↩︎

  5. For example, “apple” is a prefix of “applesauce”, but not a prefix of “application”.↩︎

  6. The official R documentation calls this an unambiguous match (“R: Extract or Replace Parts of an Object n.d.)]↩︎

Related