Using '[' square bracket as a function for lapply in R

I've seen the function lapply used in R to extract elements from matrices that exist in a list of matrices.

E.g. I have a list of 3 (2x2) matrices, and I want to extract element [1,2] from each of those 3 matrices.

The code: list1 = lapply(mylist, '[', 1,2) works just fine. It returns a list with those 3 elements.

I am trying to research what this is exactly doing. Google hasn't helped and using ?'[' in the R help isn't too explanatory. I don't see how '[' is a function in R, so the code is not intuitive.


The square brackets are in fact a function whose first argument is the object being subsetted. Subsequent arguments are the index to that subset.

# For example, if M is a matrix
M[1, 2]  # extracts the element at row 1, col 2
# is the same as 
`[`(M, 1, 2)
# Try them! 

Now, Have a look at the arguments to lapply:

args(lapply)
# function (X, FUN, ...) 

Everything represented in those dots gets passed on to the function FUN as arguments.

Thus, when FUN="[", the first argument to "[" is the current element of the list (being iterated over), ie, the object being subsetted. While the subsequent arguments are the indexes to "["


Operators in R are just functions.

These are equivalent:

> x <- list(a=1,b=2)
> x[1]
$a
[1] 1

> `[`(x,1)
$a
[1] 1

The backticks are necessary only to prevent interpretation by the parser (e.g. to tell it it's a function name not to start interpreting the [ prematurely).

Being a function, it follows the same object-oriented rules (in this case, S3) as everything else.

> methods(`[`)
 [1] [.acf*             [.arrow*           [.AsIs             [.bibentry*        [.cluster*         [.data.frame       [.data.table*     
 [8] [.Date             [.difftime         [.envlist*         [.factor           [.formula*         [.fractions*       [.getAnywhere*    
[15] [.gList*           [.gpar*            [.gtable*          [.hexmode          [.idf*             [.indexed*         [.insensitive*    
[22] [.ITime*           [.listof           [.noquote          [.numeric_version  [.octmode          [.pdf_doc*         [.person*         
[29] [.POSIXct          [.POSIXlt          [.quoted*          [.raster*          [.roman*           [.shingle*         [.simple.list     
[36] [.split*           [.terms*           [.trellis*         [.ts*              [.tskernel*        [.uneval*          [.unit*           
[43] [.unit.arithmetic* [.unit.list*       [.vpPath*         

   Non-visible functions are asterisked

+, =, etc. and other operators all work this way as well.