0

I am learning R from the book 'The Art of R Programming' and I have the following code:

> g
[1] "M" "F" "F" "I" "M" "M" "F"

> grps <- list()
> for (gen in c("M", "F", "I")) grps[[gen]] <- which(g==gen)
> grps
$M 
[1] 1 5 6 

$F
[1] 2 3 7

$I
[1] 4

I understand how the which() function works. However, for the line for(gen in c("M", "F", "I")) grps[[gen]] <- which(g==gen), why is it grps[[gen]] and not grps[gen]? Any insights are appreciated.

ceno980
  • 2,003
  • 1
  • 19
  • 37
  • 1
    I wonder if [this question](https://stackoverflow.com/questions/1169456/the-difference-between-bracket-and-double-bracket-for-accessing-the-el) helps you. – jazzurro Mar 01 '20 at 00:27

1 Answers1

0

The double bracket [[ gives you the content of the list member. You can reference it by name (as in your example) or by index (a number):

my_list <- list(a = 1, b = 2, c = 3)
> my_list[[2]]
[1] 2
> str(my_list[[2]])
num 2

Note that the result of [[ is the content of the element, or the element itself which can be overwritten. In contrast, the single bracket is used to slice a list - you can extract one or more members by position index, logical or logical vector or name/name vector. But the resulting structure is not the content, but a list - a sub-list of the original list, so to say:

> my_list[2]
$b
[1] 2    
> str(my_list[2])
List of 1
$ b: num 2
> str(my_list[c(1,2)])
List of 2
 $ a: num 1
 $ b: num 2

If you were to use grps[gen], then you would try to assign a vector (of match results) to a list slice, which feels odd:

my_list["some_unknown_element"] <- 1:3
Warning message:
In my_list["some_unknown_element"] <- 1:3 :
  number of items to replace is not a multiple of replacement length

In contrast, my_list[["some_unknown_element2"]] is the real (not yet existing) element member and not some sub-list. It can be assigned any value, e.g.:

my_list[["some_unknown_element2"]] <- 1:3
my_list["some_unknown_element2"]
$some_unknown_element2
[1] 1 2 3
shosaco
  • 5,915
  • 1
  • 30
  • 48