2015-06-15 174 views
1

我有一個矩陣A,它有大量的行和列(下面是這樣的矩陣的一個例子),偶爾有一整行0值(如在這個特定例子中的第4行) 。R:矩陣行操作

我想要一個函數來檢查A的所有行,並允許我對這些行的每個元素執行一個操作。有沒有簡單的方法來做到這一點?

我也不知道矩陣是否適合這個數據結構。它感覺不太對,也許數據框更好?

A = matrix(
    c(0, 0, 1, 0, 0, 0, 0, 
    1, 0, 1, 1, 0, 0, 0, 
    0, 0, 0, 1, 1, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 1, 1, 
    0, 0, 0, 1, 1, 0, 1), nrow=7,ncol=7,byrow = TRUE) 

對於該矩陣的每一行,我想確定它是否只有0。如果是這樣,我想設置(對於每個元素)值1/N(其中N是ncol(A))。

須藤代碼:

如果(總和(A列)== 0) 然後row_of_A = 1/NcoI位(A)

+0

請更具體,descibe你想要做的完全操作。你可以使用'apply'來遍歷矩陣行,但可能會有更高效的選擇。 – Roland

+0

對於矩陣的每一行,我想確定是否只有0。如果是這樣,我想設置(對於每個元素)值1/N(其中N是ncol(A))。 Sudo代碼:If(sum(row of A)== 0)then row_of_A = 1/ncol(A) – RalfB

+0

請將此添加到問題中(通過編輯問題)。 – Roland

回答

4

顯然希望此:

A[rowSums(A != 0) == 0,] <- 1/ncol(A) 
#   [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7] 
#[1,] 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 
#[2,] 1.0000000 0.0000000 1.0000000 1.0000000 0.0000000 0.0000000 0.0000000 
#[3,] 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 0.0000000 0.0000000 
#[4,] 0.1428571 0.1428571 0.1428571 0.1428571 0.1428571 0.1428571 0.1428571 
#[5,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 
#[6,] 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 0.0000000 1.0000000 
#[7,] 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 

說明:

  • A != 0檢查所有矩陣元素並返回一個邏輯矩陣TRUE非零元素。
  • 然後,我們對該邏輯矩陣的行進行求和,由此FALSE/TRUE被強制爲0/1。
  • 我們檢查這些rowsums是否爲0,並使用生成的邏輯向量來對行進行子集劃分。
  • 我們給這個子集分配1/ncol。

基準測試表明,apply較慢:

set.seed(42); A = matrix(sample(0:1, 5e4, TRUE), nrow=1e4) 

library(microbenchmark) 
microbenchmark(A[rowSums(A != 0) == 0,], 
       A[!apply(A != 0, 1, any),], 
       A[apply(A == 0, 1, all),]) 
#Unit: microseconds 
#      expr  min  lq  mean median  uq  max neval cld 
# A[rowSums(A != 0) == 0, ] 572.202 593.298 620.7931 624.248 629.638 780.387 100 a 
# A[!apply(A != 0, 1, any), ] 14978.248 16124.652 17261.9530 17441.054 18129.975 22469.219 100 b 
# A[apply(A == 0, 1, all), ] 15182.122 16149.751 17616.8010 16561.657 17997.703 75148.079 100 b 
+0

是否有一個更一般的命令,我可以只注入一個函數,在每行上單獨執行(對於所有行)? – RalfB

+0

是的,請閱讀我上面的評論。但是,這種方法相對較慢。 – Roland

+0

任何使用'rowSums'而不是'any'或'all'的理由? – MichaelChirico