Home > Mobile >  Remove elements of named list that match pattern (ending in dash) in R
Remove elements of named list that match pattern (ending in dash) in R

Time:09-30

This seems easier than I am making it out to be, but I have a named list and want to remove all elements within it that end with a dash and keep all the rest. So using this example:

testlist <- list(test1 = c("hi", "no","yes"), test2 = c("hello", "nein", "never-"), test3 = c("ja"))

$test1
[1] "hi"  "no"  "yes"

$test2
[1] "hello"  "nein"   "never-"

$test3
[1] "ja"

I want to have exactly the same thing, except remove never- from the vector test2 like this:

$test1
[1] "hi"  "no"  "yes"

$test2
[1] "hello"  "nein"   

$test3
[1] "ja"

I have tried this, and it removes the ones with dashes, but it leaves character(0) for those that didn't have any elements with a dash at the end.

lapply(testlist, function(z){ z[-(grep("*\\-$", z))] })

$test1
character(0)

$test2
[1] "hello" "nein" 

$test3
character(0)

I am very confused because the regexp works for a plain character vector, just not a list. So I think it is how I am implementing the loop that is the problem.

test.vec <- c("hi", "no","yes","hello", "nein", "never-","ja")
[1] "hi"     "no"     "yes"    "hello"  "nein"   "never-" "ja"

test.vec[-(grep("*\\-$", test.vec))]
[1] "hi"    "no"    "yes"   "hello" "nein"  "ja"

Thank you for reading!

CodePudding user response:

Use grep with value = TRUE and invert = TRUE (to return the values that doesn't match the pattern

lapply(testlist, grep, pattern = "-$", invert = TRUE, value = TRUE)

-output

$test1
[1] "hi"  "no"  "yes"

$test2
[1] "hello" "nein" 

$test3
[1] "ja"

grep with - is buggy, instead can use grepl with negate (!) i.e. if we don't find a pattern, it returns integer(0)

> v1 <- c('hello', 'thanks')
> grep('-$', v1)
integer(0)
> -grep('-$', v1)
integer(0)
> v1[-grep('-$', v1)]
character(0)
> v1[!grepl("-$", v1)]
[1] "hello"  "thanks"
> grep("-$", v1, invert = TRUE, value = TRUE)
[1] "hello"  "thanks"
  • Related