I have the following list that I would like to transform into the matrix M:
L<-list(c(2L, 29L, 30L), c(1L, 3L, 30L, 31L), c(2L, 31L, 32L), c(5L,
60L), c(4L, 6L, 60L, 61L), c(5L, 7L, 61L, 62L))
[[1]]
[1] 2 29 30
[[2]]
[1] 1 3 30 31
[[3]]
[1] 2 31 32
[[4]]
[1] 5 60
[[5]]
[1] 4 6 60 61
[[6]]
[1] 5 7 61 62
Matrix M:
2 29 30 NA
1 3 30 31
2 31 32 NA
5 60 NA NA
4 6 60 61
5 7 61 62
I want each list to be a row of the matrix and to fill in any missing values with NA.
CodePudding user response:
Append NA
at the end of each list
element based on the max
length of the list element with length<-
and then use rbind
with do.call
mx <- max(lengths(L))
do.call(rbind, lapply(L, `length<-`, mx))
-output
[,1] [,2] [,3] [,4]
[1,] 2 29 30 NA
[2,] 1 3 30 31
[3,] 2 31 32 NA
[4,] 5 60 NA NA
[5,] 4 6 60 61
[6,] 5 7 61 62
CodePudding user response:
You could also use stri_list2matrix
function from stringi
package. This converts the vectors of list to character matrix so you should convert it to numeric if necessary like this:
L<-list(c(2L, 29L, 30L), c(1L, 3L, 30L, 31L), c(2L, 31L, 32L), c(5L,
60L), c(4L, 6L, 60L, 61L), c(5L, 7L, 61L, 62L))
library(stringi)
m <- stri_list2matrix(L, byrow=TRUE)
class(m) <- "numeric"
m
#> [,1] [,2] [,3] [,4]
#> [1,] 2 29 30 NA
#> [2,] 1 3 30 31
#> [3,] 2 31 32 NA
#> [4,] 5 60 NA NA
#> [5,] 4 6 60 61
#> [6,] 5 7 61 62
Created on 2022-07-29 by the reprex package (v2.0.1)
CodePudding user response:
There would be better ways, but this works:
L<-list(c(2L, 29L, 30L), c(1L, 3L, 30L, 31L), c(2L, 31L, 32L), c(5L,
60L), c(4L, 6L, 60L, 61L), c(5L, 7L, 61L, 62L))
out <- matrix(nrow=6, ncol=4)
for(i in 1:length(L)) {
out[i, ] <- c(L[[i]], rep(NA, (4-length(L[[i]]))))
}
out
# [,1] [,2] [,3] [,4]
# [1,] 2 29 30 NA
# [2,] 1 3 30 31
# [3,] 2 31 32 NA
# [4,] 5 60 NA NA
# [5,] 4 6 60 61
# [6,] 5 7 61 62
CodePudding user response:
Another possible solution, based on purrr::map_dfr
:
library(tidyverse)
map_dfr(L, ~ .x %>% set_names(LETTERS[1:length(.x)])) %>%
as.matrix %>% unname
#> [,1] [,2] [,3] [,4]
#> [1,] 2 29 30 NA
#> [2,] 1 3 30 31
#> [3,] 2 31 32 NA
#> [4,] 5 60 NA NA
#> [5,] 4 6 60 61
#> [6,] 5 7 61 62
And more simply:
tibble(L) %>% unnest_wider(L) %>% suppressMessages %>% as.matrix %>% unname