繁体   English   中英

将二元向量转换为二进制矩阵

[英]Transform binary vector to binary matrix

我有一个二进制向量,可以保存某些观察事件是否发生的信息:

v <- c(0,1,1,0)

我想要实现的是一个矩阵,其中包含该向量中所有双变量观测对的信息。 也就是说,如果两个观察值都为0或两个都在此向量v中有1,则它们应该在矩阵中得到1。 如果一个有0而另一个有1,那么它们应该得到0。

因此,目标是这个矩阵:

     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    0    1    0
[3,]    0    1    0    0
[4,]    1    0    0    0

主对角线是0还是1对我来说无关紧要。

是否有一种有效且简单的方法来实现这一点,不需要if语句和for循环的组合? v可能有相当大的规模。

谢谢!

我们可以使用outer

out <- outer(v, v, `==`)
diag(out) <- 0L # as you don't want to compare each element to itself
out
#     [,1] [,2] [,3] [,4]
#[1,]    0    0    0    1
#[2,]    0    0    1    0
#[3,]    0    1    0    0
#[4,]    1    0    0    0

expand.grid另一个选项是创建v与自身的成对组合,因为只有0和1的值,我们可以找到0和2的值(0 + 0和1 + 1)。

inds <- rowSums(expand.grid(v, v))
matrix(+(inds == 0 | inds == 2), nrow = length(v))


#     [,1] [,2] [,3] [,4]
#[1,]    1    0    0    1
#[2,]    0    1    1    0
#[3,]    0    1    1    0
#[4,]    1    0    0    1

因为,对角线元素对你来说并不重要,我会保持原样,或者如果你想改变,你可以使用@gusus的答案中所示的diag

另一种(效率稍低)方法比使用outer方法更为sapply

out <- sapply(v, function(x){
  x == v
})
diag(out) <- 0L
out

     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    0    1    0
[3,]    0    1    0    0
[4,]    1    0    0    0

长度为1000的矢量上的微microbenchmark

> test <- microbenchmark("LAP" = sapply(v, function(x){
+   x == v
+ }),
+ "markus" = outer(v, v, `==`), times = 1000, unit = "ms")
> test
Unit: milliseconds
   expr      min       lq     mean   median       uq       max neval
    LAP 3.973111 4.065555 5.747905 4.573002 6.324607 101.03498  1000
 markus 3.515725 3.535067 4.852606 3.694924 4.908930  84.85184  1000

如果你允许主对角线为1,那么无论v有多大,在这个矩阵中总会有两个唯一的行v1 - v 由于矩阵是对称的,因此它也有两个这样的唯一列。 这使得构造该矩阵变得微不足道。

## example `v`
set.seed(0)
v <- sample.int(2, 10, replace = TRUE) - 1L
#[1] 1 0 0 1 1 0 1 1 1 1

## column expansion from unique columns
cbind(v, 1 - v, deparse.level = 0L)[, 2 - v]
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]    1    0    0    1    1    0    1    1    1     1
# [2,]    0    1    1    0    0    1    0    0    0     0
# [3,]    0    1    1    0    0    1    0    0    0     0
# [4,]    1    0    0    1    1    0    1    1    1     1
# [5,]    1    0    0    1    1    0    1    1    1     1
# [6,]    0    1    1    0    0    1    0    0    0     0
# [7,]    1    0    0    1    1    0    1    1    1     1
# [8,]    1    0    0    1    1    0    1    1    1     1
# [9,]    1    0    0    1    1    0    1    1    1     1
#[10,]    1    0    0    1    1    0    1    1    1     1

这个矩阵的目的是什么?

如果有n0零和n1个,则矩阵将具有维度(n0 + n1) x (n0 + n1) ,但矩阵中只有(n0 x n0 + n1 x n1)个。 因此对于长向量v ,矩阵是稀疏的。 实际上,它具有超级稀疏性,因为它具有大量重复的行/列。

显然,如果你想在这个矩阵中存储1的位置,你可以简单地得到它而不需要形成这个矩阵。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM