20

I'm working with a long named list and I'm trying to keep/remove elements that match a certain name, within a tidyverse context, similar to

dplyr::select(contains("pattern"))

However, I'm having issues figuring it out.

library(tidyverse)

a_list <- 
  list(a = "asdfg",
       b = "qwerty",
       c = "zxcvb")

a_list %>% pluck("a") # works
a_list %>% pluck(contains("a")) #does not work

a_list[2:3] # this is what I want
a_list %>% pluck(-"a") # but this does not work
kputschko
  • 766
  • 1
  • 7
  • 21
  • 3
    Based on [this question](https://stackoverflow.com/questions/46983716/does-a-multi-value-purrrpluck-exist), it sounds like `pluck` is a replacement for `[[` not `[` and so there isn't a built-in way to accomplish `a_list[2:3]`. `[[` only selects [one element](https://stackoverflow.com/a/1169495/8099834) – Hallie Swan Jan 26 '18 at 19:12

6 Answers6

22

To remove by name you could use:

a_list %>% purrr::list_modify("a" = NULL)
$`b`
[1] "qwerty"

$c
[1] "zxcvb"

I'm not sure the other answers are using the name of the element, rather than the element itself for selection. The example you gave is slightly confusing since the element 'a' both contains 'a' in it's value AND is called 'a'. So it's easy to get mixed up. To show the difference I'll modify the example slightly.

b_list <- 
  list(a = "bsdfg",
       b = "awerty",
       c = "zxcvb")

b_list %>% purrr::list_modify("a" = NULL)

returns

$`b`
[1] "awerty"

$c
[1] "zxcvb"

but

purrr::discard(b_list,.p = ~stringr::str_detect(.x,"a"))

returns

$`a`
[1] "bsdfg"

$c
[1] "zxcvb"
Tom Greenwood
  • 1,502
  • 14
  • 17
15

Keeping it full tidyverse, you could do,

purrr::discard(a_list,.p = ~stringr::str_detect(.x,"a"))
joran
  • 169,992
  • 32
  • 429
  • 468
  • If your code/package doesn't have stringr as a dependency: `purrr::discard(a_list,.p = ~grepl("a", .x))` – wibeasley Nov 22 '22 at 19:12
13

I know this is old, but one simple way to do this :

a_list[['a']] <- NULL
Anoushiravan R
  • 21,622
  • 3
  • 18
  • 41
Parisa
  • 448
  • 5
  • 11
5

using base R:

a_list[!grepl("a",unlist(a_list))]
$b
[1] "qwerty"

$c
[1] "zxcvb"
Onyambu
  • 67,392
  • 3
  • 24
  • 53
5

Similar to previous answer but searching names as in OP

within(a_list, rm(a))

a_list[!grepl("^a$",names(a_list))]
a_list[grepl("^a$",names(a_list))]<-NULL

a_list[-which(names(a_list)=="a")]
a_list[-which(names(a_list)!="a")]<-NULL
a_list[ which(names(a_list)=="a")]<-NULL
Ferroao
  • 3,042
  • 28
  • 53
0

Same as Parisa's answer, just fits better into tidyverse pipe chains:

library(magrittr)

a_list <-
    list(a = "asdfg",
         b = "qwerty",
         c = "zxcvb")

a_list %>%
magrittr::inset(c('a', 'c'), NULL)

Another alternative notation:

a_list %>%
`[<-`(c('a', 'b'), NULL)
deeenes
  • 4,148
  • 5
  • 43
  • 59