从矩阵列表中删除具有NA值的列

时间:2018-11-21 09:26:13

标签: r matrix na

我有一个矩阵列表,需要删除每个矩阵中包含NA值的列。

我试图将lapply与!is.na一起使用,以将其应用于整个列表中的所有矩阵,但是它返回的是一个排除了NA的向量列表,而我仍然想要一个矩阵列表(只是没有包含NA的列。

> my_list
$mat1
 V1   V2   V3
[1,] 1 5 NA
[1,] 2 6 NA
[1,] 3 7 NA
[1,] 4 8 NA

$mat2
 V1   V2   V3
[1,] 1 NA 9
[1,] 2 NA 10
[1,] 3 NA 11
[1,] 4 NA 12

> lapply(my_list,function(x) x[!is.na(x)])
$mat1
 [1]  1  2  3  4  5  6  7  8

$mat2
 [1]  1  2  3  4  9 10 11 12

我想要获得的输出是这样:

$mat1
 V1   V2
[1,] 1 5
[1,] 2 6
[1,] 3 7
[1,] 4 8

$mat2
 V1   V3
[1,] 1 9
[1,] 2 10
[1,] 3 11
[1,] 4 12

2 个答案:

答案 0 :(得分:1)

对于一个矩阵,apply(is.na(mat), 2, any)为您提供 with NA列的逻辑索引。要删除列,请执行以下操作:

mat[, !apply(is.na(mat), 2, any)]

要使用矩阵列表执行此操作,请执行以下操作:

lapply(my_list, function(mat) mat[, !apply(is.na(mat), 2, any)])

数据:

> dput(my_list)
list(structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, NA, NA, NA, 
NA), .Dim = c(4L, 3L), .Dimnames = list(NULL, c("V1", "V2", "V3"
))), structure(c(1L, 2L, 3L, 4L, NA, NA, NA, NA, 9L, 10L, 11L, 
12L), .Dim = c(4L, 3L), .Dimnames = list(NULL, c("V1", "V2", 
"V3"))))

答案 1 :(得分:0)

或者另一个选择是将tidyverse转换为select_if后的data.frame

library(tidyverse)
map(lst1, ~ .x %>% 
               as.data.frame %>% 
               select_if(~ all(!is.na(.))))
#[[1]]
#  V1 V2
#1  1  5
#2  2  6
#3  3  7
#4  4  8

#[[2]]
#  V1 V3
#1  1  9
#2  2 10
#3  3 11
#4  4 12