如何将不同长度的向量放在一个矩阵中

How to put vectors with different length together to one matrix

我有一个这样的数据框:

    id                 class  
   146                H02J
   146                F03D
   146                F03D
   287                F16F
   287                F16F
  1040                F03D
  1040                F16D
  1040                F03D
  1042                F03D
  1042                G01W
  1042                F03D
  1042                F03D
  1042                F03D
  1816                G06F
  1816                H04Q
  1816                H04L
  1816                H04W

现在我想用数值构建向量,每个向量代表一个应用程序,每个数值代表一个 class

由于向量的长度不同,我无法用向量定义矩阵,我的 R 技能,我很感谢解决这个问题的想法。

输出应该是这样的矩阵,目的是确定向量之间的距离。

> mat
     [,1] [,2] [,3] [,4] [,5]
[1,]    6    1    1   NA   NA
[2,]    3    3   NA   NA   NA
[3,]    1    2    1   NA   NA
[4,]    1    4    1    1    1
[5,]    5    8    7    9   NA

我得到了这个:

v1 <- subset(num, id==146)
v2 <- subset(num, id==287)
v3 <- subset(num, id==1040)
v4 <- subset(num, id==1042)
v5 <- subset(num, id==1816)

list <- list(c(v1), c(v2), c(v3), c(v4), c(v5))
list
max.length <- max(sapply(list, length))
list <- lapply(list, function(x) { c(x, rep(NA, max.length-length(x)))})
do.call(rbind, list)
mat <- do.call(rbind, list)

但解决方案不仅适用于这五个示例,而且适用于大量 id(矢量),无需手动输入 id 的数字。

您可以使用 plyr 包中的 rbind.fill.matrix

library(plyr)
do.call(rbind.fill.matrix,  tapply(as.integer(num$class), num$id, t))

结果:

     1 2  3  4  5
[1,] 6 1  1 NA NA
[2,] 3 3 NA NA NA
[3,] 1 2  1 NA NA
[4,] 1 4  1  1  1
[5,] 5 8  7  9 NA

您可以使用 reshape2 包中的 dcast 函数。

    library(reshape2)

    x <- dcast(num, id ~ class)

    mat <- as.matrix(x[,-1])

您应该注意,此矩阵的列名是在 class 列中找到的值。此外,NA 表示为更适合计算距离的 0。

使用 dplyrtidyr 软件包,您可以:

library(dplyr)
library(tidyr)

d %>% 
  group_by(id) %>% 
  mutate(i=1:n(),value=as.integer(class),class=NULL) %>% 
  spread(i,value)

#     id 1 2  3  4  5
# 1  146 6 1  1 NA NA
# 2  287 3 3 NA NA NA
# 3 1040 1 2  1 NA NA
# 4 1042 1 4  1  1  1
# 5 1816 5 8  7  9 NA

其中d是样本数据集:

d <- structure(list(id = c(146L, 146L, 146L, 287L, 287L, 1040L, 1040L, 
1040L, 1042L, 1042L, 1042L, 1042L, 1042L, 1816L, 1816L, 1816L, 
1816L), class = structure(c(6L, 1L, 1L, 3L, 3L, 1L, 2L, 1L, 1L, 
4L, 1L, 1L, 1L, 5L, 8L, 7L, 9L), .Label = c("F03D", "F16D", "F16F", 
"G01W", "G06F", "H02J", "H04L", "H04Q", "H04W"), class = "factor")), .Names = c("id", 
"class"), class = "data.frame", row.names = c(NA, -17L))