Nic*_*ick 370 statistics r r-faq
在R中,mean()
它median()
是标准函数,可以满足您的期望. mode()
告诉您对象的内部存储模式,而不是其参数中出现最多的值.但是有一个标准的库函数来实现向量(或列表)的统计模式吗?
Ken*_*ams 374
还有一个解决方案,适用于数字和字符/因子数据:
Mode <- function(x) {
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
Run Code Online (Sandbox Code Playgroud)
在我的小机器上,可以在大约半秒钟内生成并找到10M整数向量的模式.
如果您的数据集可能有多种模式,则上述解决方案采用与该方法相同的方法which.max
,并返回该组模式的第一个出现值.要返回所有模式,请使用此变体(来自注释中的@digEmAll):
Modes <- function(x) {
ux <- unique(x)
tab <- tabulate(match(x, ux))
ux[tab == max(tab)]
}
Run Code Online (Sandbox Code Playgroud)
Geo*_*tas 64
存在一种包modeest
,其提供单变量单峰(有时是多模)数据模式的估计量以及通常概率分布模式的值.
mySamples <- c(19, 4, 5, 7, 29, 19, 29, 13, 25, 19)
library(modeest)
mlv(mySamples, method = "mfv")
Mode (most likely value): 19
Bickel's modal skewness: -0.1
Call: mlv.default(x = mySamples, method = "mfv")
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅此页面
Dan*_*Dan 57
在r邮件列表中找到了这个,希望它有用.这也是我的想法.你需要table()数据,排序然后选择第一个名字.它是hackish但应该工作.
names(sort(-table(x)))[1]
Run Code Online (Sandbox Code Playgroud)
jpr*_*lly 45
我发现肯·威廉姆斯在上面的帖子很棒,我添加了几行来解释NA值并使其变得容易.
Mode <- function(x, na.rm = FALSE) {
if(na.rm){
x = x[!is.na(x)]
}
ux <- unique(x)
return(ux[which.max(tabulate(match(x, ux)))])
}
Run Code Online (Sandbox Code Playgroud)
Ras*_*åth 30
快速而肮脏的方法来估计您认为来自连续单变量分布(例如正态分布)的数字向量的模式是定义和使用以下函数:
estimate_mode <- function(x) {
d <- density(x)
d$x[which.max(d$y)]
}
Run Code Online (Sandbox Code Playgroud)
然后得到模式估计:
x <- c(5.8, 5.6, 6.2, 4.1, 4.9, 2.4, 3.9, 1.8, 5.7, 3.2)
estimate_mode(x)
## 5.439788
Run Code Online (Sandbox Code Playgroud)
Chr*_*ris 14
以下功能有三种形式:
method ="mode"[default]:计算单峰向量的模式,否则返回NA
方法="nmodes":计算向量
方法中的模式数="模式":列出单峰或多模的所有模式向量
modeav <- function (x, method = "mode", na.rm = FALSE)
{
x <- unlist(x)
if (na.rm)
x <- x[!is.na(x)]
u <- unique(x)
n <- length(u)
#get frequencies of each of the unique values in the vector
frequencies <- rep(0, n)
for (i in seq_len(n)) {
if (is.na(u[i])) {
frequencies[i] <- sum(is.na(x))
}
else {
frequencies[i] <- sum(x == u[i], na.rm = TRUE)
}
}
#mode if a unimodal vector, else NA
if (method == "mode" | is.na(method) | method == "")
{return(ifelse(length(frequencies[frequencies==max(frequencies)])>1,NA,u[which.max(frequencies)]))}
#number of modes
if(method == "nmode" | method == "nmodes")
{return(length(frequencies[frequencies==max(frequencies)]))}
#list of all modes
if (method == "modes" | method == "modevalues")
{return(u[which(frequencies==max(frequencies), arr.ind = FALSE, useNames = FALSE)])}
#error trap the method
warning("Warning: method not recognised. Valid methods are 'mode' [default], 'nmodes' and 'modes'")
return()
}
Run Code Online (Sandbox Code Playgroud)
teu*_*cer 10
这里,另一个解决方案
freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])
Run Code Online (Sandbox Code Playgroud)
Seb*_*ian 10
fmode
现在 CRAN 上可用的包中的通用函数collapse
实现了基于索引哈希的基于 C++ 的模式。它比上述任何方法都要快得多。它附带了向量、矩阵、data.frames 和 dplyr 分组 tibbles 的方法。句法:
library(collapse)
fmode(x, g = NULL, w = NULL, ...)
Run Code Online (Sandbox Code Playgroud)
其中x
可以是上述对象之一,g
提供可选的分组向量或分组向量列表(用于分组模式计算,也在 C++ 中执行),并且w
(可选)提供数字权重向量。在分组 tibble 方法中,没有g
参数,你可以这样做data %>% group_by(idvar) %>% fmode
。
我还不能投票,但RasmusBåå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)]
}
Run Code Online (Sandbox Code Playgroud)
我们知道您可能不想限制所有发行版,然后从= - "BIG NUMBER"设置为="BIG NUMBER"
肯威廉姆斯答案的一个小修改,添加了可选的参数na.rm
和return_multiple
.
与所依赖的答案不同names()
,此答案维护x
返回值中的数据类型.
stat_mode <- function(x, return_multiple = TRUE, na.rm = FALSE) {
if(na.rm){
x <- na.omit(x)
}
ux <- unique(x)
freq <- tabulate(match(x, ux))
mode_loc <- if(return_multiple) which(freq==max(freq)) else which.max(freq)
return(ux[mode_loc])
}
Run Code Online (Sandbox Code Playgroud)
要显示它与可选参数一起使用并维护数据类型:
foo <- c(2L, 2L, 3L, 4L, 4L, 5L, NA, NA)
bar <- c('mouse','mouse','dog','cat','cat','bird',NA,NA)
str(stat_mode(foo)) # int [1:3] 2 4 NA
str(stat_mode(bar)) # chr [1:3] "mouse" "cat" NA
str(stat_mode(bar, na.rm=T)) # chr [1:2] "mouse" "cat"
str(stat_mode(bar, return_mult=F, na.rm=T)) # chr "mouse"
Run Code Online (Sandbox Code Playgroud)
感谢@Frank的简化.
我编写了以下代码以生成模式.
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)))
}
Run Code Online (Sandbox Code Playgroud)
我们来试试吧:
MODE(mtcars)
MODE(CO2)
MODE(ToothGrowth)
MODE(InsectSprays)
Run Code Online (Sandbox Code Playgroud)
基于@Chris的函数计算模式或相关指标,但使用Ken Williams的方法计算频率.这个提供了对没有模式的情况的修复(所有元素同样频繁),以及一些更易读的method
名称.
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'")
}
Run Code Online (Sandbox Code Playgroud)
由于它使用Ken的方法计算频率,性能也得到了优化,使用AkselA的帖子我对一些先前的答案进行了基准测试,以显示我的函数如何接近Ken的性能,各种输出选项的条件仅导致轻微的开销:
小智 6
这个hack应该可以正常工作.给你价值以及模式的数量:
Mode <- function(x){
a = table(x) # x is a vector
return(a[which.max(a)])
}
Run Code Online (Sandbox Code Playgroud)
这是建立在 jprocckbelly 的答案的基础上的,通过增加非常短的向量的速度。当将模式应用于具有许多小组的 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)))]
}
Run Code Online (Sandbox Code Playgroud)