在R中,mean()和median()是标准函数,它们执行您所期望的功能。Mode()告诉您对象的内部存储模式,而不是参数中出现次数最多的值。但是是否存在一个标准库函数来实现向量(或列表)的统计模式?
当前回答
基于@Chris的函数来计算模态或相关指标,但是使用Ken Williams的方法来计算频率。这个方法修复了根本没有模式(所有元素频率相等)的情况,并提供了一些更易读的方法名。
Mode <- function(x, method = "one", na.rm = FALSE) {
x <- unlist(x)
if (na.rm) {
x <- x[!is.na(x)]
}
# Get unique values
ux <- unique(x)
n <- length(ux)
# Get frequencies of all unique values
frequencies <- tabulate(match(x, ux))
modes <- frequencies == max(frequencies)
# Determine number of modes
nmodes <- sum(modes)
nmodes <- ifelse(nmodes==n, 0L, nmodes)
if (method %in% c("one", "mode", "") | is.na(method)) {
# Return NA if not exactly one mode, else return the mode
if (nmodes != 1) {
return(NA)
} else {
return(ux[which(modes)])
}
} else if (method %in% c("n", "nmodes")) {
# Return the number of modes
return(nmodes)
} else if (method %in% c("all", "modes")) {
# Return NA if no modes exist, else return all modes
if (nmodes > 0) {
return(ux[which(modes)])
} else {
return(NA)
}
}
warning("Warning: method not recognised. Valid methods are 'one'/'mode' [default], 'n'/'nmodes' and 'all'/'modes'")
}
由于它使用Ken的方法来计算频率,性能也得到了优化,使用AkselA的帖子,我对之前的一些答案进行了基准测试,以显示我的函数在性能上是如何接近Ken的,各种输出选项的条件只导致很小的开销:
其他回答
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课程中的“How about median and mode? 这似乎证实了(至少在写这节课的时候)R中没有模态函数(嗯…你会发现Mode()用于断言变量的类型)。
如果你问R中的内置函数,也许你可以在软件包pracma中找到它。在这个包中,有一个叫做Mode的函数。
这建立在jprockbelly的答案上,通过对非常短的向量增加速度。这在将mode应用到data.frame或包含很多小组的数据表时非常有用:
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)))]
}
这个黑客应该工作良好。给你的值以及模式的计数:
Mode <- function(x){
a = table(x) # x is a vector
return(a[which.max(a)])
}
这里有另一个解决方案:
freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])