Remove NA from list of lists

China☆狼群 提交于 2019-11-30 12:16:30

问题


I have a matrix, data.mat, that looks like:

A B C D E  
45 43 45 65 23   
12 45 56 NA NA   
13 4  34 12 NA  

I am trying to turn this into a list of lists, where each row is one list within a bigger list. I do the following:

list <- tapply(data.mat,rep(1:nrow(data.mat),ncol(data.mat)),function(i)i)

which gives me a list of lists, with NAs included, such as:

$`1`  
 [1]  45 43 45 65 23  
$`2`  
 [1]  12 45 56 NA NA  
$`3`  
 [1]  13 4 34 12 NA  

But what I want is:

$`1`  
 [1]  45 43 45 65 23  
$`2`  
 [1]  12 45 56   
$`3`  
 [1]  13 4 34 12   

Is there a good way to remove the NAs either during the tapply call or after the fact?


回答1:


Sure, you can use lapply like this:

> lapply(list, function(x) x[!is.na(x)])
$`1`
[1] 45 43 45 65 23

$`2`
[1] 12 45 56

$`3`
[1] 13  4 34 12



回答2:


Your sample data:

data.mat <- data.matrix(read.table(text = "A B C D E  
45 43 45 65 23   
12 45 56 NA NA   
13 4  34 12 NA ", header = TRUE))

To split by row:

row.list <- split(data.mat, row(data.mat))

To remove NAs:

Map(Filter, list(Negate(is.na)), row.list)

or

lapply(row.list, Filter, f = Negate(is.na))

Everything in one shot:

Map(Filter, list(Negate(is.na)), split(data.mat, row(data.mat)))



回答3:


You could do this:

apply(data.mat, 1, function(x) x[!is.na(x)])

Output:

[[1]]
 A  B  C  D  E 
45 43 45 65 23 

[[2]]
 A  B  C 
12 45 56 

[[3]]
 A  B  C  D 
13  4 34 12

If you don't want names:

apply(data.mat, 1, function(x) unname(x[!is.na(x)]))

If there is the possibility that every row has the same number of NAs, it will be safer to use:

split(apply(data.mat, 1, function(x) unname(x[!is.na(x)])), 1:nrow(data.mat))


来源:https://stackoverflow.com/questions/25777104/remove-na-from-list-of-lists

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!