如何找到统计模式?

497

R中,mean()median() 是标准函数,它们执行你期望的操作。 mode() 返回对象内部存储模式,而不是其参数中出现最多的值。但是否有一个标准库函数可以实现向量(或列表)的统计众数?


4
请问您的数据是整数、数值型还是分类型的?数值型的众数估计方法与其他类型不同,需要使用区间。请参考modeest - smci
15
为什么 R 语言没有内置的众数函数?为什么 R 认为 mode 和函数 class 是相同的? - Corey Levinson
35个回答

10
我还不能投票,但Rasmus Bååth的答案正是我在寻找的。 不过,我会稍微修改一下,使其可以约束分布,例如仅限于0到1之间的值。
estimate_mode <- function(x,from=min(x), to=max(x)) {
  d <- density(x, from=from, to=to)
  d$x[which.max(d$y)]
}

我们知道您可能不想限制任何分布,那么请设置 from=-"大数字",to="大数字"


error in density.default(x, from = from, to = to) : need at least 2 points to select a bandwidth automatically - Sergio
x 应该是一个向量。 - AleRuete

7
我已经编写了以下代码,以生成模式。
MODE <- function(dataframe){
    DF <- as.data.frame(dataframe)

    MODE2 <- function(x){      
        if (is.numeric(x) == FALSE){
            df <- as.data.frame(table(x))  
            df <- df[order(df$Freq), ]         
            m <- max(df$Freq)        
            MODE1 <- as.vector(as.character(subset(df, Freq == m)[, 1]))

            if (sum(df$Freq)/length(df$Freq)==1){
                warning("No Mode: Frequency of all values is 1", call. = FALSE)
            }else{
                return(MODE1)
            }

        }else{ 
            df <- as.data.frame(table(x))  
            df <- df[order(df$Freq), ]         
            m <- max(df$Freq)        
            MODE1 <- as.vector(as.numeric(as.character(subset(df, Freq == m)[, 1])))

            if (sum(df$Freq)/length(df$Freq)==1){
                warning("No Mode: Frequency of all values is 1", call. = FALSE)
            }else{
                return(MODE1)
            }
        }
    }

    return(as.vector(lapply(DF, MODE2)))
}

让我们来试试:

MODE(mtcars)
MODE(CO2)
MODE(ToothGrowth)
MODE(InsectSprays)

6
这个技巧应该很好用。它不仅可以给你mode的值,还可以给你计数。
Mode <- function(x){
a = table(x) # x is a vector
return(a[which.max(a)])
}

5

这是在jprockbelly的回答基础上进行的改进,通过为非常短的向量添加加速功能。当对具有许多小组的data.frame或datatable应用mode时,这非常有用:

Mode <- function(x) {
   if ( length(x) <= 2 ) return(x[1])
   if ( anyNA(x) ) x = x[!is.na(x)]
   ux <- unique(x)
   ux[which.max(tabulate(match(x, ux)))]
}

4
这很好运行。
> a<-c(1,1,2,2,3,3,4,4,5)
> names(table(a))[table(a)==max(table(a))]

3

这个问题有多种解决方案。我检查了第一个并自己编写了一个。如果对任何人有帮助,我在此发布:

Mode <- function(x){
  y <- data.frame(table(x))
  y[y$Freq == max(y$Freq),1]
}

让我们用一些例子来测试。我将采用鸢尾花数据集。让我们测试数值数据

> Mode(iris$Sepal.Length)
[1] 5

现在,鸢尾花数据集中唯一的非数字字段(种类)没有众数。让我们用自己的示例进行测试,您可以验证其正确性。

> test <- c("red","red","green","blue","red")
> Mode(test)
[1] red

编辑

如在评论中提到的那样,用户可能希望保留输入类型。在这种情况下,可以修改模式函数:

Mode <- function(x){
  y <- data.frame(table(x))
  z <- y[y$Freq == max(y$Freq),1]
  as(as.character(z),class(x))
}

该函数的最后一行仅将最终模式值强制转换为原始输入的类型。

这将返回一个因子,而用户可能希望保留输入的类型。也许可以添加一个中间步骤 y[,1] <- sort(unique(x)) - Frank

3

R有很多附加包,其中一些可能会提供数字列表/系列/向量的[统计]模式。

然而,R本身的标准库似乎没有这样的内置方法!解决此问题的一种方法是使用以下类似的结构(如果经常使用,则将其转换为函数...):

mySamples <- c(19, 4, 5, 7, 29, 19, 29, 13, 25, 19)
tabSmpl<-tabulate(mySamples)
SmplMode<-which(tabSmpl== max(tabSmpl))
if(sum(tabSmpl == max(tabSmpl))>1) SmplMode<-NA
> SmplMode
[1] 19

对于更大的样本列表,应考虑使用临时变量来存储max(tabSmpl)值(我不知道R是否会自动优化此操作)。

参考文献:请参见KickStarting R lesson中的"How about median and mode?"
这似乎证实了(至少在编写本课程时),R中没有mode函数(嗯...如您所发现,mode()用于断言变量类型)。


3
以下是在R中查找向量变量的众数的代码:
a <- table([vector])

names(a[a==max(a)])

3

以下是一个查找众数的函数:

mode <- function(x) {
  unique_val <- unique(x)
  counts <- vector()
  for (i in 1:length(unique_val)) {
    counts[i] <- length(which(x==unique_val[i]))
  }
  position <- c(which(counts==max(counts)))
  if (mean(counts)==max(counts)) 
    mode_x <- 'Mode does not exist'
  else 
    mode_x <- unique_val[position]
  return(mode_x)
}

2

虽然我喜欢Ken Williams的简单函数,但如果存在多个模式,我希望能够检索它们。 有了这个想法,我使用以下函数,它返回多个模式的列表,如果只有一个则返回单个模式。

rmode <- function(x) {
  x <- sort(x)  
  u <- unique(x)
  y <- lapply(u, function(y) length(x[x==y]))
  u[which( unlist(y) == max(unlist(y)) )]
} 

1
如果它始终返回一个列表,对于编程使用来说会更加一致 - 如果只有一个模式,则列表长度为1。 - asachet
这是一个很好的观点,@antoine-sac。我喜欢这个解决方案的原因是返回的向量使得答案容易被访问。只需访问函数的输出:r <- mode(c(2, 2, 3, 3)),然后可以在r[1]和r[2]中找到可用的模式。你说得也很对!! - RandallShanePhD
准确地说,这就是你的解决方案存在问题的地方。如果mode返回一个包含多个值的列表,则r [1]不是第一个值;它实际上是一个长度为1的列表,其中包含第一个值,因此您必须执行r [[1]]以将第一个模式作为数字而不是列表获取。现在,当只有一个模式时,您的r不是一个列表,因此r [1]有效,这就是我认为它不一致的原因。但是,由于r是一个简单向量时,r [[1]]也有效,因此实际上存在一致性,我之前没有意识到,即您始终可以使用[[来访问元素。 - asachet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接