【发布时间】:2016-12-20 10:24:10
【问题描述】:
考虑由两个 ID 变量和第三个变量 relate 组成的 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 对和相关值中获取 平衡、对称值矩阵?
我想到的一个解决方案是使用mapply 手动填充上述NA 值的对称矩阵并定义一个子集函数,但这似乎不必要地麻烦。
【问题讨论】:
-
既然你已经分配了一个“矩阵”——比如
mat-,你可以使用mat[as.matrix(example[1:2])] = example$relate -
@alexis_laz 非常优雅——想扩大答案吗?
标签: r data.table reshape outer-join reshape2