簡體   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