1

Dummy example:

1> L = vector('list',100)#prefill empty list
1> for (i in 1:100){
1+ L[[i]]$letter = letters[rgeom(1,.5)+1]#populate it with a letter
1+ L[[i]]$number = runif(1)#and a number
1+ }
1> i = ceiling(runif(100,0,100))#an (arbitrary) vector of indices
1> x = L[[i]]$letter #I want the ith letter
Error in L[[i]] : no such index at level 2

I want x to contain the letter object of the ith element of L. (the order of i doesn't have anything to do with the index order of x)

What is a good way to do this without a loop?

Here is copy/paste from my editor, instead of my terminal window, for those who may find it easier:

L = vector('list',100)
for (i in 1:100){
    L[[i]]$letter = letters[rgeom(1,.5)+1]
    L[[i]]$number = runif(1)
}
i = ceiling(runif(100,0,100))
x = L[[i]]$letter
generic_user
  • 3,430
  • 3
  • 32
  • 56
  • Your `1>` and `+` at the start of lines makes it a pain to copy-paste and try your code – Frank Nov 13 '15 at 01:51
  • @Frank how's that for you? – generic_user Nov 13 '15 at 01:54
  • 1
    Sure, thanks. The problem seems to be: `i` is a vector, not a number while `[[]]` only takes a single number. If you want to grab the `letter` for each of those numbers, `sapply(L[i], \`[[\`, "letter")` should work. Not sure if that's what you're after. – Frank Nov 13 '15 at 02:00
  • Indeed it is. You want to make that an answer and explain why quoting a couple of brakets makes any sense, and I'll totally accept it. – generic_user Nov 13 '15 at 02:03

1 Answers1

2

The relevant documentation is at help("[["):

The most important distinction between [, [[ and $ is that the [ can select more than one element whereas the other two select a single element.

So, we need to pull values out with L[i].

From there, to access the $letter part of each of the elements of L[i], we can use sapply:

sapply(L[i], `[[`, "letter")

It's tempting to use $ instead of [[ here, but for obscure reasons, it's not a good idea.


Comment. Here's an alternative way of building some example data.

set.seed(1)
L = replicate(100, list(
  letter = letters[rgeom(1,.5)+1], 
  number = runif(1)
), simplify = FALSE)
i = sample(100, 100, replace=TRUE)

It's often useful to put a set.seed ahead of a randomly-generated example so everyone's looking at the same thing.

Community
  • 1
  • 1
Frank
  • 66,179
  • 8
  • 96
  • 180