generic_user
generic_user

Reputation: 3562

How to pull values out of a list based on a vector of list indices in R

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

Upvotes: 1

Views: 52

Answers (1)

Frank
Frank

Reputation: 66819

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.

Upvotes: 2

Related Questions