我有一个这样的数据帧:
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
使用dplyr
和tidyr
包,您可以执行:
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))
您可以使用reshape2
包中的dcast
函数。
library(reshape2)
x <- dcast(num, id ~ class)
mat <- as.matrix(x[,-1])
您应该注意,此矩阵的列名是在类列中找到的值。此外,NA被表示为0,这更适合于计算距离。