Is there a logical way to think about indexing a list?

What is the main logic or philosophical basis for understanding the difference between mylist[2] and mylist[[2]] in the following?

What is a simple logical way to understand single square brackets or double square brackets?

 > mylist <- list(1, list("a","b","c")) > mylist[2] # [[1]] # [[1]][[1]] # [1] "a" # [[1]][[2]] # [1] "b" # [[1]][[3]] # [1] "c" > mylist[[2]] # [[1]] # [1] "a" # [[2]] # [1] "b" # [[3]] # [1] "c" 
+7
list r
source share
1 answer

A simple analogy is to consider the list as a train. Every car in a train carries things. If you remove two cars, you will have a train with two smaller cars. If you delete everything except one car, this is another train with one car.

  • Reducing the size of a train or reorganizing the order of cars can be achieved using the function [] (subsets).
  • To check the contents of a particular car, you need to open the doors, which is achieved using [[]] (although $ can also be used with a named list). I see this as a retrieval function, although I'm not sure if this is a commonly used term.

In your example, mylist [2] is a mylist sublist containing one item. You can check this with length(mylist[2]) . If the arguments are valid, the function [ will provide a list with as many elements as in the number or character vector provided as the argument [ . Most often, we are interested in the contents of a list item. This is achieved using the [[ . For example, mylist[[2]] is the content of mylist[2] , which itself is a list containing several items. To see this, try length(mylist[[2]])

Since [ can be considered as a function of a subset of the list and [[ as a function of extracting the list item, mylist[1:2] and mylist[c(1,2)] returns a sublist (which is equivalent to mylist in this case), whereas mylist[[1:2]] and mylist[[c(1,2)]] return an error "index beyond borders". You can only retrieve one list item at a time (i.e. per function call).

@ richard-scriven warned me of a link to a Hadley Wickham blog post , providing an additional analogy of a nested list in the form of photographs.

With a fairly simple list structure, str is a great way to get an idea of ​​the contents of a list. In this example, the output of str(mylist[2]) and str(mylist[[2]]) provides an additional understanding of their various data structures.

In general, a list is agnostic to its contents, so that one list can contain other lists, data.frames, matrices, and atomic vectors as separate elements. Like @joran, joked in his comment, this is where train analogs stretch out, maybe too much. However, as soon as you feel comfortable with the first level of the list, additional nested lists behave the same. (perhaps nested lists - boxes transported inside the car?)

Side note:
One of my favorite functions for checking lists and data.frames (which are lists with atomic vectors of total length) is the str function. I regularly use it after reading in .csv, .dta or another file to check the list structure. A common obstacle for users learning R (as well as experienced users) in the debugging code is to take into account the data structure they work with, and which data structure is needed as an argument, or for which data structure is the result of the function. str along with typeof and class is a great toolkit to solve this problem.

This answer benefits from comments from @ 42, @nicola, @joran, @jogo and @ richard-scriven.

+7
source share

All Articles