【问题标题】:quickest way in R to check that all columns are identicalR中检查所有列是否相同的最快方法
【发布时间】:2014-10-08 17:10:59
【问题描述】:

假设我有一个包含 3 列的矩阵

10             10                       10
8              8                        8
9              9                        9
7              7                        7
5              5                        5
4              4                        4
3              3                        3
6              6                        6
2              2                        2
1              1                        1

检查所有列是否相同的最快方法是什么?我可以使用allidentical 之类的方法检查任意两个,然后继续与下一组崩溃,但还有什么更聪明的方法吗?

理想情况下,我想要一个独立于列数的解决方案。

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    你可以试试:

     all(m1[,1]==m1)
     # [1] TRUE
     all(m2[,1]==m2)
     #[1] FALSE
    

    数据

     m1 <- matrix(c(10:1, 10:1, 10:1), ncol=3)
     m2 <- cbind(m1, 11:2)
    

    【讨论】:

    • 如果问题需要知道哪些行相同,哪些行不同,请改为:rowSums(m[,1]==m1) == ncol(m1)
    【解决方案2】:

    也许

     all(duplicated(t(m))[-1])
    

    会起作用。这会转置矩阵(因为duplicated 按行工作),然后检查除第一行之外的每一行是否与前一行重复。

    @akrun 的回答可能稍微快一些。这两个答案都依赖于对行/列结构的了解:在@akrun 的情况下,矩阵以列优先顺序存储(因此复制第一列以匹配完整解压缩矩阵的长度将起作用),在我的情况下duplicated 按行工作。

    如果你想避免这些知识,你可以使用

    all(sweep(m,MARGIN=1,STATS=m[,1],FUN="=="))
    

    (对每一列与m[,1]的对应元素进行逐元素比较,然后查看所有比较是否为真)

    【讨论】:

      【解决方案3】:

      您可以使用 rankMatrix 函数来确定您有多少线性独立的列。在结果都相同的情况下,应该是1。

      require(Matrix)  # now a recommended package so it ships with R
      m <- matrix(10:1, 10,3)
      rankMatrix(m)==1
      #[1] TRUE
      

      【讨论】:

        【解决方案4】:

        您可以在unique 中指定MARGIN 参数以仅获取矩阵中的唯一列:

        ncol(unique(m, MARGIN = 2)) == 1L
        

        就“最快”而言,这是我机器上的结果:

        library(microbenchmark)
        
        microbenchmark(
          all(m[,1]==m),
          all(duplicated(t(m))[-1]),
          ncol(unique(m, MARGIN = 2)) == 1L,
          Matrix::rankMatrix(m) == 1L,
          times = 5000L
        )
        
        Unit: nanoseconds
                                      expr   min    lq      mean median     uq     max neval  cld
                          all(m[, 1] == m)   900  1600   2383.40   2000   2500   44900  5000 a   
                 all(duplicated(t(m))[-1]) 28000 33800  47087.68  38200  45650 5065500  5000  b  
         ncol(unique(m, MARGIN = 2)) == 1L 31800 37800  52746.86  43300  52100 4444300  5000   c 
               Matrix::rankMatrix(m) == 1L 62500 76300 105550.94  81500 103800 5107700  5000    d
        

        【讨论】:

          猜你喜欢
          • 2023-03-16
          • 2012-12-16
          • 2010-11-24
          • 1970-01-01
          • 2017-11-01
          • 2014-06-05
          • 2020-03-30
          • 1970-01-01
          相关资源
          最近更新 更多