【问题标题】:Most frequent value (mode) by group [duplicate]按组划分的最常见值(模式)[重复]
【发布时间】:2015-05-29 02:42:00
【问题描述】:

我正在尝试按组查找最常见的值。在以下示例数据框中:

df<-data.frame(a=c(1,1,1,1,2,2,2,3,3),b=c(2,2,1,2,3,3,1,1,2))  
> df  
  a b  
1 1 2  
2 1 2  
3 1 1  
4 1 2  
5 2 3  
6 2 3  
7 2 1  
8 3 1  
9 3 2  

我想添加一个列“c”,当它的值按“a”分组时,它在“b”中出现次数最多。我想要以下输出:

> df  
  a b c  
1 1 2 2    
2 1 2 2    
3 1 1 2    
4 1 2 2    
5 2 3 3    
6 2 3 3    
7 2 1 3    
8 3 1 1   
9 3 2 1    

我尝试使用 table 和 tapply,但没有做对。有没有快速的方法来做到这一点?
谢谢!

【问题讨论】:

  • 这个和this很相关

标签: r


【解决方案1】:

以 Davids cmets 为基础,您的解决方案如下:

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

library(dplyr)
df %>% group_by(a) %>% mutate(c=Mode(b))

请注意,当df$a3 时,b 的模式为1

【讨论】:

    【解决方案2】:

    我们可以使用 ave 获得按“a”分组的“b”的“模式”

     Mode <- function(x) {
     ux <- unique(x)
     ux[which.max(tabulate(match(x, ux)))]
    }
    
    df$c <-  with(df, ave(b, a, FUN=Mode))
    df$c
    #[1] 2 2 2 2 3 3 3 1 1
    

    或使用data.table

    library(data.table)
    setDT(df)[, c:= Mode(b), by=a][]
    

    【讨论】:

    • 谢谢@akrun!要从模式函数中排除 NA,请将第二行更改为 'ux
    【解决方案3】:

    这是一个基本的 R 方法,它使用table 计算交叉表,max.col 查找每个组的模式,reprle 一起填写跨组的模式。

    # calculate a cross tab, frequencies by group
    myTab <- table(df$a, df$b)
    # repeat the mode for each group, as calculated by colnames(myTab)[max.col(myTab)] 
    # repeating by the number of times the group ID is observed
    df$c <- rep(colnames(myTab)[max.col(myTab)], rle(df$a)$length)
    
    df
      a b c
    1 1 2 2
    2 1 2 2
    3 1 1 2
    4 1 2 2
    5 2 3 3
    6 2 3 3
    7 2 1 3
    8 3 1 2
    9 3 2 2
    

    请注意,这假设数据已按组排序。此外,max.col 的默认设置是随机打破平局(多种模式)。如果您希望第一个或最后一个值成为模式,您可以使用 ties.method 参数进行设置。

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 2021-09-16
      • 2018-09-08
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      相关资源
      最近更新 更多