111

I have a list in R some 10,000 elements long. Say I want to select only elements, 5, 7, and 9. I'm not sure how I would do that without a for loop.

I want to do something like mylist[[c(5,7,9]] but that doesn't work. I've also tried the lapply function but haven't been able to get that working either.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
user1357015
  • 11,168
  • 22
  • 66
  • 111
  • 22
    From the documentation found at `?"[["`: *The most important distinction between `[`, `[[` and `$` is that the `[` can select more than one element whereas the other two select a single element.* – A5C1D2H2I1M1N2O1R2T1 Aug 25 '12 at 04:05
  • 1
    Further to @mrdwab's comment, this being the vectorised world of R, "a single element" may be a vector! – seancarmody Aug 25 '12 at 04:37

2 Answers2

175

mylist[c(5,7,9)] should do it.

You want the sublists returned as sublists of the result list; you don't use [[]] (or rather, the function is [[) for that -- as Dason mentions in comments, [[ grabs the element.

Glen_b
  • 7,883
  • 2
  • 37
  • 48
  • 10
    Just to add some more detail - "[" will return a sublist so it makes sense that you could use multiple inputs with it. "[[" will actually grab the element itself so it can only take a single input since it isn't returning a list (unless the element itself is a list). – Dason Aug 25 '12 at 04:15
  • Is this vectorized? I have two lists: `b` contains 10 million elements. `filter_bins` is a list where each element is an index. so to only get elements from `b` with the same index, I have `lapply(filter_bins, function(x) b[x, ])` so b[x, ] only returns a subset of the rows (where each element is chosen by filter_bins).. I hope this makes sense. My question is that this is very slow – masfenix Oct 23 '14 at 19:35
  • @masfenix you should generate a new question describing the details. – Glen_b Nov 14 '14 at 08:53
  • Can the above solution be done with something like dplyr::select() and contains('some text")? – derelict May 05 '16 at 17:32
  • @Dason how do you then select multiple elements with [[? – Herman Toothrot Apr 25 '18 at 15:31
  • 3
    @HermanToothrot You don't. At least not directly. You could lapply or sapply over the indices you want to extract and iteratively grab the corresponding element with `[[`. But if you want to extract multiple elements then really you're grabbing a sublist and you should just use `[` – Dason Apr 25 '18 at 15:44
0

Glen_b's answer is the correct one. Below are some examples of how you can use it with pipes, functions like lapply and map(), and within a dataframe with list columns:

With pipes:

library(tidyverse)

x <- as.list(letters)
nums <- c(5, 7, 9)

x[nums] # Glen's answer

nums |> x[i = _] # using the native pipe

nums %>% {x[.]} # using magrittr's pipe
# nums %>% x[i = .] is equivalent

Using map(), lapply() etc.

y = list(as.list(letters), as.list(LETTERS))

map(y, \(x) x[nums]) # lambda function \(x) x[nums] is equivalent to ~ .x[nums] or function(x){x[nums]}
lapply(y, \(x) x[nums])

With list-type columns in dataframes:

df <- tibble(
    x = list(x)) # we need to put x within another list, as tibble() will unnest x otherwise

df |> 
  mutate(z = map(x, \(x) x[nums])) |> 
  pull(z)
Mark
  • 7,785
  • 2
  • 14
  • 34