首页 文章

R:矩阵行操作

提问于
浏览
1

我有一个矩阵A,它有大量的行和列(在这样一个矩阵的一个例子下面),偶尔会有一个完整的0行值(如在这个特定的例子中的第4行) .

我想要一个检查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)) .

Sudo代码:

如果(sum(A行)== 0)则row_of_A = 1 / ncol(A)

1 回答

  • 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 .

    • 我们检查这些rowums是否为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
    

相关问题