The [
and [[
operators are primitive functions that are generic. This means that any object in R (specifically isTRUE(is.object(x))
--i.e. has an explicit "class" attribute) can have its own specified behaviour when subsetted; i.e. has its own methods for [
and/or [[
.
For example, this is the case with "data.frame" (is.object(iris)
) objects where [.data.frame
and [[.data.frame
methods are defined and they are made to exhibit both "matrix"-like and "list"-like subsetting. With forcing an error when subsetting a "data.frame", we see that, actually, a function [.data.frame
was called when we -just- used [
.
iris[invalidArgument, ]
## Error in `[.data.frame`(iris, invalidArgument, ) :
## object 'invalidArgument' not found
Without further details on the current topic, an example[
method:
x = structure(1:5, class = "myClass")
x[c(3, 2, 4)]
## [1] 3 2 4
'[.myClass' = function(x, i) cat(sprintf("We'd expect '%s[%s]' to be returned but this a custom `[` method and should have a `?[.myClass` help page for its behaviour\n", deparse(substitute(x)), deparse(substitute(i))))
x[c(3, 2, 4)]
## We'd expect 'x[c(3, 2, 4)]' to be returned but this a custom `[` method and should have a `?[.myClass` help page for its behaviour
## NULL
We can overcome the method dispatching of [
by using the equivalent non-generic .subset
(and .subset2
for [[
). This is especially useful and efficient when programming our own "class"es and want to avoid work-arounds (like unclass(x)
) when computing on our "class"es efficiently (avoiding method dispatch and copying objects):
.subset(x, c(3, 2, 4))
## [1] 3 2 4