【问题标题】:Subtract maximum per row每行减去最大值
【发布时间】:2019-04-12 01:03:16
【问题描述】:

假设您想从相应行中减去矩阵每一行的最大值。你可以使用这样的循环来做到这一点:

# create matrix
mat <- matrix(rnorm(100),ncol=5,nrow=20)

for(i in 1:nrow(mat)){    #for each row
  row.max <- max( mat[i,] ) #take the maximum of the row
  mat[i,] <- mat[i,] - row.max  #subtract it from the row
}

我正在考虑一种以矢量化方式执行此操作的方法,也许可以使用 max.col() ,但是,到目前为止我还想不出什么办法。有什么想法吗?

谢谢!

编辑:

感谢您的回答,我接受了(迄今为止)最快的解决方案。

Unit: microseconds
    expr      min        lq       mean    median        uq       max neval
    loop 4671.687 4906.6820 5124.78995 5019.7965 5214.5935 12318.986   100
   apply   41.055   47.0430   60.58208   57.0925   71.6320   158.661   100
 rowMaxs    2.139    2.9945    6.21019    5.3465    8.9810    12.402   100
 do.call  111.618  125.0890  154.46904  142.4095  170.2065   422.522   100

【问题讨论】:

  • 一种方法是mat - apply(mat, 1, max)

标签: r matrix max vectorization


【解决方案1】:

您可以使用library(matrixStats) 并简单地使用,

mat - rowMaxs(mat)

matrixStats 行所示,此解决方案速度极快。(@hrbrmstr 提供的基准测试)

## Unit: microseconds
##         expr     min       lq      mean   median       uq      max neval
##     base_mat  33.084  39.3215  46.93637  46.3575  49.6435  116.293   100
##      base_df  80.769  98.9870 116.05771 112.8985 127.6595  201.791   100
##  matrixStats   2.111   3.0170   4.99795   4.9655   5.8415   27.240   100
##    qlcMatrix 716.229 742.2140 834.73351 782.1605 888.4960 1491.734   100

【讨论】:

  • 一些matrixStats 函数应该成为基本函数。在base 中还有一个max.col 给出了每行最大值的索引,所以rowMaxcolMax 应该很容易实现。
【解决方案2】:

Base R 选项将是

mat - do.call(pmax, data.frame(mat))

 #           [,1]       [,2]       [,3]       [,4]       [,5]
 #[1,] -2.6565620 -1.9266890 -1.3154080 -0.3471987  0.0000000
 #[2,]  0.0000000 -1.2758157 -0.7681151 -0.7530223 -1.3460720
 #[3,]  0.0000000 -1.8606951 -1.5249890 -1.7938812 -1.9398058
 #[4,] -2.8052871 -0.3951306  0.0000000 -0.9608475 -0.7402124
 #[5,] -0.5303694  0.0000000 -1.6532143 -2.5885875 -1.9538341
 #[6,]  0.0000000 -0.6163414 -1.9542608 -1.6736752 -1.4745702
 #[7,] -1.1494957 -1.0857652  0.0000000 -2.7547954 -1.6820739
 #[8,]  0.0000000 -0.3645636 -0.4770239 -0.7943613 -0.7053540
 #[9,] -0.5493137 -0.8220334  0.0000000 -0.2791556 -0.5086898
 #[10,] -3.3058730  0.0000000 -3.3517838 -2.8817327 -2.9126851

数据

set.seed(1234)
mat <- matrix(rnorm(100),ncol=5,nrow=10)

【讨论】:

    【解决方案3】:

    有一个名为qlcMatrix 的包具有rowMax;colMax;rowMin;colMin 的功能。

    使用此包,您可以执行mat - rowMax(mat) 形式的操作。

    【讨论】:

    • 不幸的是,qlcMatrix::rowMax() 返回的稀疏向量对象不能轻易地从矩阵中减去。它给出了一个Error: not-yet-implemented method for -(&lt;matrix&gt;, &lt;dsparseVector&gt;). -&gt;&gt; Ask the package authors to implement the missing feature. 错误。
    • 这就像打电话给 as.numeric() 一样简单,这在我的 not-an-answer-answer 中,我想现在是一个答案
    猜你喜欢
    • 2017-12-17
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多