仅附加不是 "TRUE" 的列表元素

only append list elements that are not "TRUE"

我有三个列表:test1test2test3:

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

在这些列表中,我只想保留 NOT TRUE 的信息。为此,我使用 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)])

现在,我想将 test1、test2 和 test3 附加到一个具有相同名称的列表元素的空列表中。但是,我只想附加文本条目。文本可能会有所不同,并且无法通过字符匹配来做到这一点。我目前得到:

$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)

期望的结果是:

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


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

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


$test3
NULL

我怎样才能避免logical(0)并获得我想要的结果?

这几乎给出了预期的结果:

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

这给出:

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


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

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


$test3
named list()

唯一的区别是 named list() 对应 test3。但这种行为可能取决于 R 版本(我使用的是 3.6.3)。

要获得 NULL,请将此代码应用于此新列表:

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

您可以使用 [:

而不是使用 lapply 删除 TRUE
test1[test1 == TRUE] <- NULL
test2[test2 == TRUE] <- NULL
test3[test3 == TRUE] <- NULL

要获取列表,您可以使用 mget

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

或在@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

选项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()

基本 R 选项

> 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()