【问题标题】:How to find min and max for each row of a matrix?如何找到矩阵每一行的最小值和最大值?
【发布时间】:2020-10-11 15:35:54
【问题描述】:

假设我们有以下矩阵m

[1] "list of respective positions"
             [,1]      [,2]      [,3]      [,4]       [,5]
x:      2.4131066 3.8504796 3.7434050 -1.923839 2.41310661
y:      0.0260981 0.7128027 0.7128027  1.396096 0.01565761
obj-val 0.7937068 0.3105951 0.4038012  1.195259 0.83750443

如何检索每行的最小值和最大值? (我需要矩阵每一行的一对(最小,最大)m

我不想使用包Rfastrowmins()

【问题讨论】:

标签: r


【解决方案1】:

你可以使用apply:

my_mat <- matrix(rnorm(25), nrow = 5, dimnames = list(letters[1:5], NULL))

my_mat
#>         [,1]        [,2]       [,3]        [,4]        [,5]
#> a -1.7455936  0.79571392  0.1509219 -0.61944619 -0.65429261
#> b  0.5858837 -0.32462380  1.3739094 -0.08092246 -1.24418958
#> c  1.0757723 -0.23296522 -2.2174416  0.56720160 -0.02991945
#> d  1.8043565 -0.00370110 -1.4628807 -0.73418720  0.10333882
#> e -0.4153639 -0.07896341  1.0089698 -0.09542518  0.17067607

t(apply(my_mat, 1, function(x) c(min = min(x), max = max(x))))
#>          min       max
#> a -1.7455936 0.7957139
#> b -1.2441896 1.3739094
#> c -2.2174416 1.0757723
#> d -1.4628807 1.8043565
#> e -0.4153639 1.0089698

reprex package (v0.3.0) 于 2020 年 6 月 21 日创建

【讨论】:

    【解决方案2】:

    使用 Allan Cameron 的示例矩阵,您可以 apply range 函数

    my_mat <- matrix(rnorm(25), nrow = 5, dimnames = list(letters[1:5], NULL))
    my_mat
    #         [,1]       [,2]       [,3]       [,4]        [,5]
    # a  1.7813097 -0.4946628  2.0344305  0.2620399  0.99000423
    # b  1.0758692  0.4004411 -1.2957444  0.3443362 -0.71271404
    # c  0.9705851 -0.1952594 -0.6168627 -0.3046352 -1.04132273
    # d -0.5459703 -0.2538314 -1.6677170 -0.6585102 -0.06104492
    # e -0.4463699 -0.3935345  0.6689235  0.5235429  0.40823566
    apply(my_mat, 1, range)
    #               a         b          c           d          e
    # [1,] -0.4946628 -1.295744 -1.0413227 -1.66771703 -0.4463699
    # [2,]  2.0344305  1.075869  0.9705851 -0.06104492  0.6689235
    

    【讨论】:

      【解决方案3】:

      matrix转换为data.frame后,我们可以使用pminpmax

      cbind(min = do.call(pmin, as.data.frame(my_mat)), 
                   max = do.call(pmax, as.data.frame(my_mat)))
      #           min       max
      #[1,] -1.3169081 0.2660220
      #[2,] -0.6051569 0.5982691
      #[3,] -1.7096452 1.5362522
      #[4,] -1.4290903 0.6099945
      #[5,] -0.6485915 0.8474600
      

      或者使用rowMins/rowMaxs from matrixStats

      library(matrixStats)
      cbind(min = rowMins(my_mat), max = rowMaxs(my_mat))
      #         min       max
      #[1,] -1.3169081 0.2660220
      #[2,] -0.6051569 0.5982691
      #[3,] -1.7096452 1.5362522
      #[4,] -1.4290903 0.6099945
      #[5,] -0.6485915 0.8474600
      

      或者更简洁的rowRanges

      rowRanges(my_mat)
      #           [,1]      [,2]
      #[1,] -1.3169081 0.2660220
      #[2,] -0.6051569 0.5982691
      #[3,] -1.7096452 1.5362522
      #[4,] -1.4290903 0.6099945
      #[5,] -0.6485915 0.8474600
      

      或者使用transmute

      library(dplyr)
      as.data.frame(my_mat) %>%
         transmute(min = pmin(!!! .), max = pmax(!!! .))
      #        min       max
      #1 -1.3169081 0.2660220
      #2 -0.6051569 0.5982691
      #3 -1.7096452 1.5362522
      #4 -1.4290903 0.6099945
      #5 -0.6485915 0.8474600
      

      或者rowwise/c_across

      library(tidyr)
      as.data.frame(my_mat) %>% 
          rowwise %>% 
          summarise(out = list(as.list(range(c_across(everything()))))) %>% 
          unnest_wider(c(out), names_repair = ~ c('min', 'max'))
      # A tibble: 5 x 2
      #     min   max
      #   <dbl> <dbl>
      #1 -1.32  0.266
      #2 -0.605 0.598
      #3 -1.71  1.54 
      #4 -1.43  0.610
      #5 -0.649 0.847
      

      基准测试

      set.seed(24)
      my_mat1 <- matrix(rnorm(5 * 1e7), nrow = 1e7)
      
      system.time(cbind(min = do.call(pmin, as.data.frame(my_mat1)), 
                     max = do.call(pmax, as.data.frame(my_mat1))))
      #   user  system elapsed 
      #  0.804   0.209   1.009 
      
      system.time(rowRanges(my_mat1))
      #   user  system elapsed 
      #   0.303   0.000   0.303 
      
      system.time(apply(my_mat1, 1, range))
      #   user  system elapsed 
      # 30.373   0.455  31.037 
      
      
      
      system.time(t(apply(my_mat1, 1, function(x) c(min = min(x), max = max(x)))))
      #   user  system elapsed 
      # 34.594   0.728  35.240 
      

      数据

      set.seed(24)
      my_mat <- matrix(rnorm(25), nrow = 5, dimnames = list(letters[1:5], NULL))
      

      【讨论】:

        【解决方案4】:
        [1] "list of respective positions"
                      [,1]       [,2]      [,3]      [,4]       [,5]
        x:      3.69250663 3.75443457 4.4075606 3.7544346 4.16053631
        y:      0.61196240 0.61196240 0.6899600 0.6899600 0.68996003
        obj-val 0.05702941 0.08390476 0.1334916 0.2036376 0.07759858
        
        MIN_t=apply(D, 1, min)   
        MAX_t=apply(D, 1, max)   
        New_domain_search=cbind(MIN_t,MAX_t)
        

        输出:

                     MIN_t     MAX_t
        x:      3.69250663 4.4075606
        y:      0.61196240 0.6899600
        obj-val 0.05702941 0.2036376
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-03-19
          • 2014-06-17
          • 2013-11-20
          • 2019-04-25
          • 2017-07-25
          • 1970-01-01
          • 2018-12-25
          • 1970-01-01
          相关资源
          最近更新 更多