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?
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
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)))
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))