r-基于逻辑条件的列表中的子集元素



如何根据另一个列表中的条件(TRUE,FALSE(对列表进行子集设置?请看下面的例子:

l <- list(a=c(1,2,3), b=c(4,5,6,5), c=c(3,4,5,6))
l
$a
[1] 1 2 3
$b
[1] 4 5 6 5
$c
[1] 3 4 5 6
cond <- lapply(l, function(x) length(x) > 3)
cond
$a
[1] FALSE
$b
[1] TRUE
$c
[1] TRUE
> l[cond]

l[cond]中的错误:无效的下标类型"list">

这就是Filter函数的用途:

Filter(function(x) length(x) > 3, l)
$b
[1] 4 5 6 5
$c
[1] 3 4 5 6

另一种方法是使用sapply而不是lapply

cond <- sapply(l, function(x) length(x) > 3)
l[cond]

[需要一个向量,因此在cond:上使用unlist

l[unlist(cond)]
$b
[1] 4 5 6 5
$c
[1] 3 4 5 6
> l[as.logical(cond)]
$b
[1] 4 5 6 5
$c
[1] 3 4 5 6

我最近学习了lengths(),它可以获取列表中每个元素的长度。这使我们可以避免在OP尝试时制作另一个包含逻辑值的列表。

lengths(l)
#a b c 
#3 4 4 

在逻辑条件下使用它,我们可以对l中的列表元素进行子集化。

l[lengths(l) > 3]
$b
[1] 4 5 6 5
$c
[1] 3 4 5 6

我对R很陌生,但由于它是一种函数式语言,根据前面的答案,最好的解决方案是:

filter <- function (inputList, selector) sapply(inputList, function (element) selector(element))

假设你有一个像你的复杂列表:

myList <- list(
    a=c(1,2,3), 
    b=c(4,5,6,5), 
    c=c(3,4,5,6))

然后你可以过滤元素,比如:

selection <- myList[filter(myList, function (element) length(element) > 3]

当然,这也适用于只包含第一级值的列表:

anotherList <- list(1, 2, 3, 4)
selection <- myList[filter(anotherList, function (element) element == 2)]

或者你可以把它们放在一起,比如:

filter <- function (inputList, selector) inputList[sapply(inputList, function (element) selector(element))]
cond <- lapply(l, length) > 3
l[cond]
l <- list(a=c(1,2,3), b=c(4,5,6,5), c=c(3,4,5,6))
l[lengths(l) > 3]
$b
[1] 4 5 6 5
$c
[1] 3 4 5 6

如果需要上的条件:

cond <- lapply(l, function(i) i > 3)
res <- Map(`[`, l, cond)
res
$a
numeric(0)
$b
[1] 4 5 6 5
$c
[1] 4 5 6

最新更新