简体   繁体   English

R:矩阵行运算

[英]R: Matrix row operations

I have a matrix A that has a large number of rows and columns (below one example of such a matrix) that occasionally has a full row of 0 values (as in row 4 at this particular example). 我有一个矩阵A,它具有大量的行和列(在这样的矩阵的一个示例下面),偶尔具有一整行的0值(如在此特定示例中的第4行)。

I want to have a function that checks all rows of A and allows me to perform an operation on each element of these rows. 我想拥有一个检查A的所有行并允许我对这些行的每个元素执行操作的函数。 Is there an easy way to do that? 有没有简单的方法可以做到这一点?

I also wonder if matrix is the right data structure for this. 我也想知道矩阵是否是正确的数据结构。 It feels not quite right, perhaps data frames are better for that? 感觉不太正确,也许数据帧对此更好?

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)

For every row of that matrix I want to determine if there are only 0's in it. 对于该矩阵的每一行,我都想确定其中是否只有0。 If so, I want to set (for each element) the value 1/N (where N is the ncol(A)). 如果是这样,我想为每个元素设置值1 / N(其中N是ncol(A))。

Sudo code: 须藤代码:

If (sum(row of A) == 0) then row_of_A = 1/ncol(A) 如果(sum(A行)== 0),则row_of_A = 1 / ncol(A)

Apparently you want this: 显然,您需要这样做:

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

Explanation: 说明:

  • A != 0 checks all matrix elements and returns a logical matrix with TRUE for non-zero elements. A != 0检查所有矩阵元素,并为非零元素返回逻辑为TRUE的逻辑矩阵。
  • We then sum the rows of that logical matrix, whereby FALSE / TRUE is coerced to 0/1. 然后,我们对该逻辑矩阵的行求和,从而将FALSE / TRUE强制为0/1。
  • We check if these rowsums are 0 and use the resulting logical vector to subset the rows. 我们检查这些行和是否为0,并使用结果逻辑向量对行进行子集化。
  • We assign 1/ncol to this subset. 我们给这个子集分配1 / ncol。

Benchmarks to show that apply is slower: 基准表明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

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

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