Home > Blockchain >  Return full list if element to remove from list is not found
Return full list if element to remove from list is not found

Time:06-16

I have a list for which i can remove element(s) from it based on the presence of a pattern (see this post).

lst <- list(a = 1:4, b = 4:8, c = 8:10)

pattern <- "a|c"
lstnew <- lst[-grep(pattern, names(lst))]

The above code removes elements a and c from the list. Great. Sometimes though I have no matching pattern in the list. I then want it to return the full list. If i use the above code, it returns an empty named list.

pattern <- "d|c"
lstnew <- lst[-grep(pattern, names(lst))]

lstnew
named list()

It seems like an ifelse() is a logical choice to achieve this i.e. if pattern has a match in list, remove elements from list, otherwise return full list. Any suggestions?

CodePudding user response:

Use grepl to get a logical vector for subsetting:

lst <- list(a = 1:4, b = 4:8, c = 8:10)

pattern <- "a|c"
grepl(pattern, names(lst))
#[1]  TRUE FALSE  TRUE
lst[!grepl(pattern, names(lst))]
#$b
#[1] 4 5 6 7 8

pattern <- "d|e"
grepl(pattern, names(lst))
#[1] FALSE FALSE FALSE
lst[!grepl(pattern, names(lst))]
#$a
#[1] 1 2 3 4
#
#$b
#[1] 4 5 6 7 8
#
#$c
#[1]  8  9 10

CodePudding user response:

This is an issue with negation. When there are no matches, grep returns an integer(0) hence the - sign does not do anything. Consider using grepl instead

lst[!grepl('e|f', names(lst))]
$a
[1] 1 2 3 4

$b
[1] 4 5 6 7 8

$c
[1]  8  9 10

CodePudding user response:

Here is another possible option with stringr, where you could use negate:

library(stringr)

lst <- list(a = 1:4, b = 4:8, c = 8:10)

pattern <- "a|c"
lst[str_subset(names(lst), pattern, negate = T)]
# $b
# [1] 4 5 6 7 8

pattern <- "d|e"
lst[str_subset(names(lst), pattern, negate = T)]
#$a
#[1] 1 2 3 4

#$b
#[1] 4 5 6 7 8

#$c
#[1]  8  9 10
  • Related