【问题标题】:Expand unblanced data.frame of values relating two ID variables to balanced matrix展开将两个 ID 变量关联到平衡矩阵的非平衡数据帧
【发布时间】: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 中,反之亦然。

目标是将这些数据扩展为一个对称矩阵,其中v1v2 中的所有唯一值都包含行名和列名,并且条目是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::dcastreshape2: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


【解决方案1】:

我们可以将“v1/v2”列转换为factor,并将levels指定为“example”中unlisted“v1/v2”列中的unique元素,然后执行@987654325 @与drop=FALSE

library(data.table)
un1 <- unique(unlist(example[1:2]))
setDT(example)[, paste0("v", 1:2) := lapply(.SD, factor, levels = un1), 
            .SDcols = v1:v2]
dcast(example, v1~v2, value.var = "relate", drop = FALSE)
#   v1     B    C  A     D  G    E    H     I
#1:  B -0.63 0.18 NA -0.84 NA   NA   NA    NA
#2:  C    NA   NA NA  1.60 NA 0.33   NA    NA
#3:  A    NA   NA NA -0.82 NA 0.49   NA    NA
#4:  D    NA   NA NA    NA NA 0.74   NA    NA
#5:  G    NA   NA NA    NA NA   NA 0.58 -0.31
#6:  E    NA   NA NA    NA NA   NA   NA    NA
#7:  H    NA   NA NA    NA NA   NA   NA    NA
#8:  I    NA   NA NA    NA NA   NA   NA    NA

【讨论】:

  • 正是我想要的——尝试指定drop = FALSE,但没有指定额外的因子水平。干杯。
猜你喜欢
  • 2011-12-24
  • 1970-01-01
  • 2016-12-31
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多