![](/img/trans.png)
[英]R, Trying to transform a vector of integer to a specific binary Matrix
[英]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
有多大,在這個矩陣中總會有兩個唯一的行v
和1 - 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.