【问题标题】:In R, how do I add a max by group? [duplicate]在 R 中,如何按组添加最大值? [复制]
【发布时间】:2012-07-25 09:46:30
【问题描述】:

我想使用 R 在我的数据集中创建一个新列,其中包含每个唯一组的最大值。我的数据如下所示:

group<-c("A","A","A","A","A","B","B","C","C","C")
replicate<-c(1,2,3,4,5,1,2,1,2,3)
x<-data.frame(cbind(group,replicate))

我想创建如下所示的第三列 - 每个组的最大值。

group   replicate max.per.group
A       1         5       
A       2         5
A       3         5
A       4         5
A       5         5
B       1         2
B       2         2
C       1         3
C       2         3
C       3         3

【问题讨论】:

  • @akrun 使用平均值,而这个有最大值:stackoverflow.com/questions/35617665/…(它也被标记为欺骗,但它的目标有一个坏的标题。)或者这个:stackoverflow.com/q/12379043 虽然它有包标签。
  • @Frank 另外,我觉得旧问题不应该被标记为与新问题重复。反之亦然。
  • @Frank 这看起来像是更合适的欺骗目标,虽然我不会关闭它,因为它是一个较新的目标
  • @RonakShah 我一般同意,但如果新问题的答案要好得多,那么我认为可以将旧问题视为重复问题,这样人们就会得到最佳答案。跨度>

标签: r


【解决方案1】:

我们可以使用data.table赋值(:=)在原地创建一列而不需要复制

library(data.table)
setDT(x)[, max.per.group := max(replicate), by = group]
x
#     group replicate max.per.group
#1:     A         1             5
#2:     A         2             5
#3:     A         3             5
#4:     A         4             5
#5:     A         5             5
#6:     B         1             2
#7:     B         2             2
#8:     C         1             3
#9:     C         2             3
#10:    C         3             3

数据

x <- data.frame(group,replicate)

【讨论】:

    【解决方案2】:

    共享的可重现示例表明您将列作为因子。我们需要先将它们转换为数字。

    我们可以尝试使用 base R ave。找出每个组中的最大值。

    x$max.per.group <- ave(x$replicate, x$group, FUN = function(x) max(as.numeric(x)))
    
    #   group replicate max.per.group
    #1      A         1             5
    #2      A         2             5
    #3      A         3             5
    #4      A         4             5
    #5      A         5             5
    #6      B         1             2
    #7      B         2             2
    #8      C         1             3
    #9      C         2             3
    #10     C         3             3
    

    dplyr 的另一个选项

    library(dplyr)
    x %>%
       group_by(group) %>%
       mutate(max.per.group = max(as.numeric(replicate)))
    

    【讨论】:

      【解决方案3】:

      你可以使用rle - Run Length Encoding

      # Create the data.frame
      group <- c("A","A","A","A","A","B","B","C","C","C")
      replicate <- c(1,2,3,4,5,1,2,1,2,3)
      x <- data.frame(group,replicate)
      
      # using 'rle'
      z <- rle(as.numeric(x$group))$lengths
      x$max.per.group <- rep(z, z)
      x
      

      【讨论】:

      • 这假定replicate 对于每个组从 1 开始,并且对于每个后续条目递增 1。这个假设对于这个例子是正确的(并且可能对于更普遍的问题),但它不一定是,其他一些答案也没有假设它。
      【解决方案4】:

      如果您首先重新定义xcbind 使两列都成为因子),

      x<-data.frame(group,replicate)
      

      你可以用这个:

      merge(x,aggregate(replicate~group,x,FUN=max),all.x=TRUE,by="group")
         group replicate.x replicate.y
      1      A           1           5
      2      A           2           5
      3      A           3           5
      4      A           4           5
      5      A           5           5
      6      B           1           2
      7      B           2           2
      8      C           1           3
      9      C           2           3
      10     C           3           3
      

      【讨论】:

        【解决方案5】:

        这是另一种基本的 R 解决方案:

        cbind(x, cummax=unlist(tapply(x$replicate, x$group, function(x) rep(max(x), length(x)))))
           group replicate cummax
        A1     A         1      5
        A2     A         2      5
        A3     A         3      5
        A4     A         4      5
        A5     A         5      5
        B1     B         1      2
        B2     B         2      2
        C1     C         1      3
        C2     C         2      3
        C3     C         3      3
        

        【讨论】:

          【解决方案6】:

          试试

          # This is how you create your data.frame
          group<-c("A","A","A","A","A","B","B","C","C","C")
          replicate<-c(1,2,3,4,5,1,2,1,2,3)
          x<-data.frame(group,replicate) # here you don't need c()
          
          # Here's my solution    
          Max <- tapply(x$replicate, x$group,max)
          data.frame(x, max.per.group=rep(Max, table(x$group)))
           group replicate max.per.group
          1      A         1             5
          2      A         2             5
          3      A         3             5
          4      A         4             5
          5      A         5             5
          6      B         1             2
          7      B         2             2
          8      C         1             3
          9      C         2             3
          10     C         3             3
          

          【讨论】:

            【解决方案7】:

            您可以使用plyr 包:

            library(plyr)
            > ddply(x, .(group), transform, max.per.group=max(replicate))
               group replicate max.per.group
            1      A         1             5
            2      A         2             5
            3      A         3             5
            4      A         4             5
            5      A         5             5
            6      B         1             2
            7      B         2             2
            8      C         1             3
            9      C         2             3
            10     C         3             3
            > 
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-12-27
              • 1970-01-01
              • 2013-12-28
              • 2016-06-07
              • 2020-02-01
              • 2013-09-20
              相关资源
              最近更新 更多