Skip to contents

Check that the [[ operator is used when extracting a single element from an object, not [ (subsetting) nor $ (interactive use).

Usage

extraction_operator_linter()

Details

There are three subsetting operators in R ([[, [, and $) and they interact differently with different data structures (atomic vector, list, data frame, etc.).

Here are a few reasons to prefer the [[ operator over [ or $ when you want to extract an element from a data frame or a list:

  • Subsetting a list with [ always returns a smaller list, while [[ returns the list element.

  • Subsetting a named atomic vector with [ returns a named vector, while [[ returns the vector element.

  • Subsetting a data frame (but not tibble) with [ is type unstable; it can return a vector or a data frame. [[, on the other hand, always returns a vector.

  • For a data frame (but not tibble), $ does partial matching (e.g. df$a will subset df$abc), which can be a source of bugs. [[ doesn't do partial matching.

For data frames (and tibbles), irrespective of the size, the [[ operator is slower than $. For lists, however, the reverse is true.

References

  • Subsetting chapter from Advanced R (Wickham, 2019).

See also

linters for a complete list of linters available in lintr.

Examples

# will produce lints
lint(
  text = 'iris["Species"]',
  linters = extraction_operator_linter()
)
#> ::warning file=<text>,line=1,col=5::file=<text>,line=1,col=5,[extraction_operator_linter] Use `[[` instead of `[` to extract an element.

lint(
  text = "iris$Species",
  linters = extraction_operator_linter()
)
#> ::warning file=<text>,line=1,col=5::file=<text>,line=1,col=5,[extraction_operator_linter] Use `[[` instead of `$` to extract an element.

# okay
lint(
  text = 'iris[["Species"]]',
  linters = extraction_operator_linter()
)