我有两个矢量的两个列表。我想从每个子列表中删除零向量。
x <- list(x1=c(0,0,0), x2=c(3,4,5), x3=c(45,34,23))
y <- list(y1=c(2,33,4), y2=c(0,0,0), y3=c(4,5,44))
z <- list(x, y)
我尝试过:
res <- lapply(1:2, function(i) {lapply(1:3, function(j) z[[i]][[j]][z[[i]][[j]] != 0])})
这是给我的:
> res
[[1]]
[[1]][[1]]
numeric(0)
[[1]][[2]]
[1] 3 4 5
[[1]][[3]]
[1] 45 34 23
[[2]]
[[2]][[1]]
[1] 2 33 4
[[2]][[2]]
numeric(0)
[[2]][[3]]
[1] 4 5 44
我不想要numeric(0)
。
x= list(x2, x3)
y=list(y1, y3)
有什么想法吗?
答案 0 :(得分:2)
如果嵌套列表结构不重要,您可以尝试tidyverse
library(tidyverse)
z %>%
flatten() %>%
keep(~all(. != 0))
$x2
[1] 3 4 5
$x3
[1] 45 34 23
$y1
[1] 2 33 4
$y3
[1] 4 5 44
答案 1 :(得分:2)
鉴于您的列表列表结构,我将使用以下内容:
filteredList <- lapply(z, function(i) Filter(function(x) any(x != 0), i))
x <- filteredList[[1]]
y <- filteredList[[2]]
x
##$`x2`
##[1] 3 4 5
##$x3
##[1] 45 34 23
y
##$`y1`
##[1] 2 33 4
##$y3
##[1] 4 5 44
答案 2 :(得分:1)
将z定义为
z <- c(x, y)
# z <- unlist(z, recursive = F) if you cannot define z by yourself.
然后使用:
z[sapply(z, any)]
#$`x2`
#[1] 3 4 5
#$x3
#[1] 45 34 23
#$y1
#[1] 2 33 4
#$y3
#[1] 4 5 44
请注意:
与lang C
的传统一样。每个整数/数字!= 0将强制转换为TRUE
。因此,在此任务中,我们可以使用此逻辑。如果所有值均为?any
,则0
的值为FALSE。
答案 3 :(得分:1)
或者:
x <- list(x1=c(0,0,0), x2=c(3,4,5), x3=c(45,34,23))
y <- list(y1=c(2,33,4), y2=c(0,0,0), y3=c(4,5,44))
z <- list(x, y)
lapply(z, function(a) a[unlist(lapply(a, function(b) !identical(b, rep(0,3))))])
#[[1]]
#[[1]]$`x2`
#[1] 3 4 5
#
#[[1]]$x3
#[1] 45 34 23
#
#
#[[2]]
#[[2]]$`y1`
#[1] 2 33 4
#
#[[2]]$y3
#[1] 4 5 44
答案 4 :(得分:1)
借助purrr
,它可以变得非常紧凑
library(purrr)
map(z, keep ,~all(.!=0))
# [[1]]
# [[1]]$x2
# [1] 3 4 5
#
# [[1]]$x3
# [1] 45 34 23
#
#
# [[2]]
# [[2]]$y1
# [1] 2 33 4
#
# [[2]]$y3
# [1] 4 5 44
如果不是因为烦人的警告,我们可以只map(z, keep , all)