only append list elements that are not "TRUE"

Viewed 61

I have three lists: test1, test2, test3:

test1 <- list(`0` = "text", `1` = T)
test2 <- list(`0` = "text", `1` = "text")
test3 <- list(`0` = T, `1` = T)

In these lists i only want to keep information that is NOT TRUE. For this i am using lapply:

test1 <- lapply(test1, function(x) x[!isTRUE(x)])
test2 <- lapply(test2, function(x) x[!isTRUE(x)])
test3 <- lapply(test3, function(x) x[!isTRUE(x)])

Now, i would like to append test1, test2 and test3 to an empty list with equally named list elements. However, i only want to append enteries that are text. The text may vary and there is no way to do this by character matching. I am currently getting:

$test1
$test1$`0`
[1] "text"

$test1$`1`
logical(0)


$test2
$test2$`0`
[1] "text"

$test2$`1`
[1] "text"


$test3
$test3$`0`
logical(0)

$test3$`1`
logical(0)

desired result is:

$test1
$test1$`0`
[1] "text"


$test2
$test2$`0`
[1] "text"

$test2$`1`
[1] "text"


$test3
NULL

How can i avoid getting logical(0) and obtain my desired result?

4 Answers

This almost gives the desired result:

lapply(
  list(test1=test1, test2=test2, test3=test3), 
  function(x){
    Filter(Negate(isTRUE), x)
  }
)

This gives:

$test1
$test1$`0`
[1] "text"


$test2
$test2$`0`
[1] "text"

$test2$`1`
[1] "text"


$test3
named list()

The only difference is the named list() for test3. But it's possible that this behavior depends on the R version (I'm using 3.6.3).

To get NULL, apply this code to this new list:

lapply(newlist, function(x) if(length(x)) x)

In stead of using lapply to remove TRUE you can use [:

test1[test1 == TRUE] <- NULL
test2[test2 == TRUE] <- NULL
test3[test3 == TRUE] <- NULL

and to get the list you can use mget

mget(c("test1", "test2", "test3"))

or inside the function already given by @stéphane-laurent:

lapply(mget(c("test1", "test2", "test3")), function(x) if(length(x)) x)
#$test1
#$test1$`0`
#[1] "text"
#
#
#$test2
#$test2$`0`
#[1] "text"
#
#$test2$`1`
#[1] "text"
#
#
#$test3
#NULL

An option with discard

library(purrr)
map(list(test1, test2, test3), discard, isTRUE)
#[[1]]
#[[1]]$`0`
#[1] "text"


#[[2]]
#[[2]]$`0`
#[1] "text"

#[[2]]$`1`
#[1] "text"


#[[3]]
#named list()

A base R option

> lapply(
+   list(test1, test2, test3),
+   function(v) v[!sapply(v, isTRUE)]
+ )
[[1]]
[[1]]$`0`
[1] "text"


[[2]]
[[2]]$`0`
[1] "text"

[[2]]$`1`
[1] "text"


[[3]]
named list()
Related