【问题标题】:Summarise a logical Matrix [duplicate]总结一个逻辑矩阵[重复]
【发布时间】:2018-11-08 16:02:06
【问题描述】:

我有一个大矩阵,每列下都填充了真/假值。有没有一种方法可以总结矩阵,使每一行都是唯一的,并且我有一个新列,其中包含该行出现频率的总和。

例子:

    A B C D E
[1] T F F T F
[2] T T T F F
[3] T F F T T
[4] T T T F F
[5] T F F T F

会变成:

    A B C D E total
[1] T F F T F  2
[2] T T T F F  2
[3] T F F T F  1

编辑

我将这个矩阵与一个新列 rev 绑定,所以我现在有一个看起来像

的 data.frame
    A B C D E rev
[1] T F F T F  2
[2] T T T F F  3
[3] T F F T T  5
[4] T T T F F  2
[5] T F F T F  1

并且想要一个对 rev 列进行如下求和的 data.frame:

    A B C D E rev total
[1] T F F T F  3    2
[2] T T T F F  5    2 
[3] T F F T T  5    1

【问题讨论】:

    标签: r matrix summarize


    【解决方案1】:

    dplyr 的方法:

    如果您从matrix 开始,请先使用as.data.frame(或此处as_tibble)。最后,您无论如何都需要有一个data.frame,因为您的表中将同时拥有numericlogical

    mat <- matrix(
     c(T, F, F, T, F, T, T, T, F, F, T, F, F, T, T, T, T, T, F, F, T, F, F, T, F),
     ncol = 5,
     byrow = TRUE,
     dimnames = list(NULL, LETTERS[1:5])
    )
    
    library(dplyr)
    mat %>%
      as_tibble %>%    # convert matrix to tibble, to be able to group
      group_by_all %>% # group by every column so we can count by group of equal values
      tally %>%        # tally will add a count column and keep distinct grouped values
      ungroup          # ungroup the table to be clean
    #> # A tibble: 3 x 6
    #>   A     B     C     D     E         n
    #>   <lgl> <lgl> <lgl> <lgl> <lgl> <int>
    #> 1 TRUE  FALSE FALSE TRUE  FALSE     2
    #> 2 TRUE  FALSE FALSE TRUE  TRUE      1
    #> 3 TRUE  TRUE  TRUE  FALSE FALSE     2
    

    reprex package (v0.2.0) 于 2018 年 5 月 29 日创建。

    还有一个基本的解决方案:

    df <- as.data.frame(mat)
    df$n <- 1
    aggregate(n~.,df,sum)
    #      A     B     C     D     E n
    # 1 TRUE  TRUE  TRUE FALSE FALSE 2
    # 2 TRUE FALSE FALSE  TRUE FALSE 2
    # 3 TRUE FALSE FALSE  TRUE  TRUE 1
    

    或者作为一个班轮:aggregate(n~.,data.frame(mat,n=1),sum)

    【讨论】:

    • 你能分解代码中到底发生了什么吗?我以前没有使用过 dplyr 包。
    • 我添加了cmets,为了理解%&gt;%关键字是pipe、dplyr和magrittr。
    • @Calum tally 与此处的计数没有任何不同
    • 我将采用基本解决方案。我更容易理解,我可以将同一行应用于不同的列。谢谢。
    • [[&lt;- 有点矫枉过正,你可以直接使用aggregate(n ~ ., data.frame(mat,n=1), FUN=sum)
    【解决方案2】:

    来自plyrcount 函数正是您正在寻找的(假设m 是您的矩阵):

    plyr::count(m)
    
    #   x.A   x.B   x.C   x.D   x.E freq
    #1 TRUE FALSE FALSE  TRUE FALSE    2
    #2 TRUE FALSE FALSE  TRUE  TRUE    1
    #3 TRUE  TRUE  TRUE FALSE FALSE    2
    

    【讨论】:

      【解决方案3】:

      如果您有@Moody_Mudskipper 的答案中定义的对象mat,您可以这样做

      library(data.table)
      dt <- as.data.table(mat)
      
      dt[, .N, by = names(dt)]
      
      #       A     B     C     D     E N
      # 1: TRUE FALSE FALSE  TRUE FALSE 2
      # 2: TRUE  TRUE  TRUE FALSE FALSE 2
      # 3: TRUE FALSE FALSE  TRUE  TRUE 1
      

      解释

      by = &lt;names&gt; 将数据表划分为多组行,其中&lt;names&gt; 中所有变量的值在各行之间是相等的。如果你这样做by = names(dt),它将分成所有变量都相等的组。

      .N 是给定行组中的观察数。

      对于您的编辑,如果您的 data.frame 被命名为df,您可以这样做

      setDT(df) # convert to data table
      df[, .(rev = sum(rev), total = .N), by = A:E] # get desired output
      
      #       A     B     C     D     E rev N
      # 1: TRUE FALSE FALSE  TRUE FALSE   3 2
      # 2: TRUE  TRUE  TRUE FALSE FALSE   5 2
      # 3: TRUE FALSE FALSE  TRUE  TRUE   5 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-23
        • 2017-09-01
        • 2021-01-13
        • 1970-01-01
        • 2016-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多