"Indexing and slicing"

Coming from other (arguably saner) programming languages, R's indexing behaviour kept catching me off guard. When should I use [] and when [[]]? What's the difference between accessing a member by name or using that name as an index? Why is iterating over a list so fiddly? Here's an example to clear things up.

Imagine a list with a numbver of named members:

mylist <- list (
   foo=c('first', 1),
   bar=c('second', 2),
   baz=c('third', 3)
)

Of course, you can access each named element with the $ syntax:

mylist$foo
## [1] "first" "1"

But if you don't know the names in advance and have to access them programmaticaly, you'll have to use [] syntax:

mylist['foo']
## $foo
## [1] "first" "1"
for (n in names (mylist)) {
   mylist[n]
}

As you can see, these things produce two slightly different results. The distinction may be a little more obvious using str:

str (mylist)
## List of 3
##  $ foo: chr [1:2] "first" "1"
##  $ bar: chr [1:2] "second" "2"
##  $ baz: chr [1:2] "third" "3"
str (mylist$foo)
##  chr [1:2] "first" "1"
str (mylist['foo'])
## List of 1
##  $ foo: chr [1:2] "first" "1"

You can see something similar happening here:

str (mylist[1])
## List of 1
##  $ foo: chr [1:2] "first" "1"
str (mylist[[1]])
##  chr [1:2] "first" "1"

In summary:

  • [] returns a slice or subset of the original object, a sublist in this case.

  • [[]] and $ return the actual values stored at that index. In effect, they strip off the name and one level of structure.

What happens if you use [[]] to return the values stored at multiple indices? Uh ...

mylist[[1:2]]
## [1] "1"

There's probably some logic to this but I can't see it.


Last posts

  1. "Using Biomart"

    tags: programmingsciencercomputational-biologybiomartgenomics

  2. Using RMarkdown documents in Pelican

    tags: programmingweb-developmentrmarkdown

  3. "Hadley’s vocabulary: part 1 - the basics"
  4. Logging PHP errors

    tags: programmingweb-developmentphp

  5. Markdown in R Studio

    tags: rr-studiomarkdownmarkupknitr