如何从r

时间:2018-11-14 11:37:17

标签: r

问题:

我有两个矢量的两个列表。我想从每个子列表中删除零向量。

示例:

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)

有什么想法吗?

5 个答案:

答案 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)