2016-09-18 83 views
0

我想在這種情況下用矩陣A中的某個值替換另一個值:1。對於A的j列,需要替換的行索引是B列中的行索引。下面我舉一個例子,其中賦值是通過for-loop實現的。R:如何在沒有for-loop的情況下分配A [B [,j],j]

我的問題是:如何實現這個任務更簡單,更高效和/或沒有for循環?

set.seed(4521) 
n <- 10 
p <- 5 

A <- matrix(rep(NaN,n*p),n,p) 

B <- replicate(p, sample(n)) 
B <- B[1:5,] 

for (j in 1:n){  
    A[B[,j],j] <- 1  
} 

print(B) 
print(A) 

B

 [,1] [,2] [,3] [,4] [,5] 
[1,] 5 10 7 6 5 
[2,] 10 2 9 9 2 
[3,] 7 9 3 10 4 
[4,] 9 4 1 3 3 
[5,] 4 8 6 4 9 

A

 [,1] [,2] [,3] [,4] [,5] 
[1,] NaN NaN 1 NaN NaN 
[2,] NaN 1 NaN NaN 1 
[3,] NaN NaN 1 1 1 
[4,]  1 1 NaN 1 1 
[5,]  1 NaN NaN NaN 1 
[6,] NaN NaN 1 1 NaN 
[7,]  1 NaN 1 NaN NaN 
[8,] NaN 1 NaN NaN NaN 
[9,]  1 1 1 1 1 
[10,] 1 1 NaN 1 NaN 

回答

0

簡單的解決方案:

A[cbind(as.numeric(B), as.numeric(col(B)))] <- 1 

感謝(和+ 1)在Zheyuan Li的第一個回答中有一個錯字col而不是ncol

5

我們可以利用矩陣索引:

i <- as.numeric(B) 
j <- rep(1:ncol(B), each = nrow(B)) 
A[cbind(i,j)] <- 1 

或者把它們放在一行:

A[cbind(as.numeric(B), rep(1:ncol(B), each = nrow(B)))] <- 1 

由於OP被後來注意到,一些DIG-在自己身上,我們可以通過更短的更換as.numeric(col(B))rep(1:ncol(B), each = nrow(B))。我知道它,但我從來沒有這樣做,因爲它使用了我建議的內存兩倍的內存。使用哪一個只是個人偏好。它只在處理大型矩陣時很重要。

2

恕我直言,它更清楚@Zheyuan李的代碼在做什麼。我寧願他的解決方案。
爲了表明一種替代方案:使用一維的索引,你可以這樣做:

An <- nrow(A) 
Bp <- ncol(B) 
offset <- rep(seq(0, An*(Bp-1), by=An), each=Bp) 
A[B + offset] <- 1 

在一個行:

A[B + rep(seq(0, nrow(A)*(ncol(B)-1), by=nrow(A)), each=ncol(B))] <- 1 
相關問題