简体   繁体   English

R 将具有不同长度的向量列表转换为矩阵

[英]R transform a list of vectors with differing lengths into a matrix

I have the following list that I would like to transform into the matrix M:我有以下列表,我想将其转换为矩阵 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.我希望每个列表都是矩阵的一行,并用 NA 填充任何缺失值。

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 Append NA在每个list元素的末尾基于length<-的列表元素的max长度,然后使用rbinddo.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

You could also use stri_list2matrix function from stringi package.您还可以使用来自stri_list2matrix package 的stringi function。 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)代表 package (v2.0.1) 于 2022 年 7 月 29 日创建

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

Another possible solution, based on purrr::map_dfr :另一种可能的解决方案,基于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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM