Check that the [[
operator is used when extracting a single element from an object,
not [
(subsetting) nor $
(interactive use).
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 subsetdf$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()
)