Как соединить векторы с разной длиной в одну матрицу
У меня есть кадр данных, как это:
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
это вручную.
3 ответа
Ты можешь использовать rbind.fill.matrix
от plyr
пакет:
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))
Вы можете использовать dcast
функция от reshape2
пакет.
library(reshape2)
x <- dcast(num, id ~ class)
mat <- as.matrix(x[,-1])
Обратите внимание, что имена столбцов для этой матрицы - это значения, найденные в столбце вашего класса. Кроме того, NA представлены как 0, которые больше подходят для вычисления расстояний.