Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: Why is the [[ ]] approach for subsetting a list faster than using $?

I've been working on a few projects that have required me to do a lot of list subsetting and while profiling code I realised that the object[["nameHere"]] approach to subsetting lists was usually faster than the object$nameHere approach.

As an example if we create a list with named components:

a.long.list <- as.list(rep(1:1000)) names(a.long.list) <- paste0("something",1:1000) 

Why is this:

system.time ( for (i in 1:10000) {     a.long.list[["something997"]] } )   user  system elapsed  0.15    0.00    0.16  

faster than this:

system.time (     for (i in 1:10000) {         a.long.list$something997     } )  user  system elapsed  0.23    0.00    0.23  

My question is simply whether this behaviour is true universally and I should avoid the $ subset wherever possible or does the most efficient choice depend on some other factors?

like image 261
Jon M Avatar asked May 18 '13 23:05

Jon M


People also ask

Can you subset a list in R?

Lists in R can be subsetted using all three of the operators mentioned above, and all three are used for different purposes. The [[ operator can be used to extract single elements from a list. Here we extract the first element of the list.

How to subset objects in R?

Method 2: Subsetting in R Using [[ ]] Operator [[ ]] operator is used for subsetting of list-objects. This operator is the same as [ ] operator but the only difference is that [[ ]] selects only one element whereas [ ] operator can select more than 1 element in a single command.

How do I select an element from a list in R?

We can use the [[index]] function to select an element in a list. The value inside the double square bracket represents the position of the item in a list we want to extract.


1 Answers

Function [[ first goes through all elements trying for exact match, then tries to do partial match. The $ function tries both exact and partial match on each element in turn. If you execute:

system.time (     for (i in 1:10000) {      a.long.list[["something9973", exact=FALSE]]      } ) 

i.e., you are running a partial match where there is no exact match, you will find that $ is in fact ever so slightly faster.

like image 121
Bojan Nikolic Avatar answered Oct 16 '22 09:10

Bojan Nikolic