Рассмотрим data.frame
, состоящий из двух переменных идентификаторов и третьей переменной, relate
, показывающим соотношение (например, ковариации) между каждой парой ID переменных:Expand unblanced data.frame значений двух переменных, относящихся к ID сбалансированной матрице
options(stringsAsFactors = FALSE, digits = 2)
set.seed(1)
(example <- data.frame(v1 = LETTERS[rep(c(2,3,1,4,7),
times = c(3,2,2,1,2))],
v2 = LETTERS[c(2:4, 4:5, 4:5, 5,8,9)],
relate = rnorm(10)))
v1 v2 relate
1 B B -0.63
2 B C 0.18
3 B D -0.84
4 C D 1.60
5 C E 0.33
6 A D -0.82
7 A E 0.49
8 D E 0.74
9 G H 0.58
10 G I -0.31
Эти данные являются неуравновешенными тем, что не каждое попарное отношение учитывается, и не каждый в v1
находится в v2
и наоборот.
Цель состоит в том, чтобы расширить эти данные в симметричную матрицу, где все уникальные значения в обоих v1
и v2
содержат имена строк и столбцов, и записей являются соответствующими значениями relate
(если она существует, то NA
). Другими словами, чтобы заполнить приведенную ниже матрицу со значениями relate
:
vars <- with(example, unique(c(v1, v2)))
matrix(nrow = length(vars),
ncol = length(vars),
dimnames = list(vars, vars))
B C A D G E H I
B NA NA NA NA NA NA NA NA
C NA NA NA NA NA NA NA NA
A NA NA NA NA NA NA NA NA
D NA NA NA NA NA NA NA NA
G NA NA NA NA NA NA NA NA
E NA NA NA NA NA NA NA NA
H NA NA NA NA NA NA NA NA
I NA NA NA NA NA NA NA NA
Однако готовых решений я пытался до сих пор (data.table::dcast
, reshape2:dcast
) производят следующие неуравновешенных результаты:
data.table::dcast(example, v1~v2, value.var = 'relate')
v1 B C D E H I
1 A NA NA -0.82 0.49 NA NA
2 B -0.63 0.18 -0.84 NA NA NA
3 C NA NA 1.60 0.33 NA NA
4 D NA NA NA 0.74 NA NA
5 G NA NA NA NA 0.58 -0.31
есть ли эффективный способ вместо того, чтобы получить сбалансированную , симметричного матрицы значений из набора ID-пар и связанные ценности?
Одно решение, которое происходит со мной, чтобы вручную заполнять выше симметричную матрицу NA
значений с помощью mapply
и определяющих функцию подмножества, но это кажется излишне громоздким.
Так как вы уже выделили «матрицу» -сайт 'mat'-, вы можете использовать' mat [as.matrix (пример [1: 2])] = пример $ relate' –
@alexis_laz очень элегантный - забота о расширении на ответ? –
Связанный: http://stackoverflow.com/questions/9617348/reshape-three-column-data-frame-to-matrix-long-to-wide-format – Frank