在R中,mean()和median()是标准函数,它们执行您所期望的功能。Mode()告诉您对象的内部存储模式,而不是参数中出现次数最多的值。但是是否存在一个标准库函数来实现向量(或列表)的统计模式?
当前回答
计算包含离散值的向量“v”的MODE的一个简单方法是:
names(sort(table(v)))[length(sort(table(v)))]
其他回答
效果很好
> a<-c(1,1,2,2,3,3,4,4,5)
> names(table(a))[table(a)==max(table(a))]
基于@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的,各种输出选项的条件只导致很小的开销:
我浏览了所有这些选项,开始想知道它们的相对特性和性能,所以我做了一些测试。如果其他人也好奇,我在这里分享我的结果。
我不想为这里发布的所有函数而烦恼,我选择了一个基于一些标准的示例:函数应该对字符、因子、逻辑和数字向量都有效,它应该适当地处理na和其他有问题的值,输出应该是“合理的”,即没有数字作为字符或其他类似的愚蠢行为。
我还添加了一个我自己的函数,它是基于与chrispy相同的想法,除了适应更一般的用途:
library(magrittr)
Aksel <- function(x, freq=FALSE) {
z <- 2
if (freq) z <- 1:2
run <- x %>% as.vector %>% sort %>% rle %>% unclass %>% data.frame
colnames(run) <- c("freq", "value")
run[which(run$freq==max(run$freq)), z] %>% as.vector
}
set.seed(2)
F <- sample(c("yes", "no", "maybe", NA), 10, replace=TRUE) %>% factor
Aksel(F)
# [1] maybe yes
C <- sample(c("Steve", "Jane", "Jonas", "Petra"), 20, replace=TRUE)
Aksel(C, freq=TRUE)
# freq value
# 7 Steve
最后,我通过微基准测试在两组测试数据上运行了五个函数。函数名指的是它们各自的作者:
Chris的函数被设置为method="modes"和na。rm=TRUE默认值,以使其更具可比性,但除此之外,这里使用的函数是由它们的作者提供的。
In matter of speed alone Kens version wins handily, but it is also the only one of these that will only report one mode, no matter how many there really are. As is often the case, there's a trade-off between speed and versatility. In method="mode", Chris' version will return a value iff there is one mode, else NA. I think that's a nice touch. I also think it's interesting how some of the functions are affected by an increased number of unique values, while others aren't nearly as much. I haven't studied the code in detail to figure out why that is, apart from eliminating logical/numeric as a the cause.
可以尝试以下功能:
将数值转换为因子 使用summary()获取频率表 返回模式为频率最大的索引 转换因子回到数字,即使有超过1个模式,这个函数工作得很好!
mode <- function(x){
y <- as.factor(x)
freq <- summary(y)
mode <- names(freq)[freq[names(freq)] == max(freq)]
as.numeric(mode)
}
这里有另一个解决方案:
freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])