在R中,mean()和median()是标准函数,它们执行您所期望的功能。Mode()告诉您对象的内部存储模式,而不是参数中出现次数最多的值。但是是否存在一个标准库函数来实现向量(或列表)的统计模式?
当前回答
抱歉,我可能把它理解得太简单了,但这不是可以工作的吗?(我的机器上的1E6值在1.3秒内):
t0 <- Sys.time()
summary(as.factor(round(rnorm(1e6), 2)))[1]
Sys.time()-t0
你只需要用你的向量替换“round(rnorm(1e6),2)”。
其他回答
下面的函数有三种形式:
method = "mode"[默认值]:计算单模态向量的模式,否则返回NA Method = "nmodes":计算vector中模式的个数 Method = "modes":列出单模态或多模态向量的所有模态
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()
}
添加raster::modal()作为一个选项,不过请注意,raster是一个很大的包,如果不做地理空间方面的工作,可能不值得安装。
源代码可以从https://github.com/rspatial/raster/blob/master/src/modal.cpp和https://github.com/rspatial/raster/blob/master/R/modal.R中取出,放入个人R包中,供那些特别热衷的人使用。
估计来自连续单变量分布(例如正态分布)的数字向量的模式的一种快速而肮脏的方法是定义并使用以下函数:
estimate_mode <- function(x) {
d <- density(x)
d$x[which.max(d$y)]
}
然后得到模态估计:
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
CRAN上现在可用的折叠包中的通用函数fmode实现了基于索引哈希的基于c++的模式。它比上述任何一种方法都要快得多。它提供了向量、矩阵、data.frames和dplyr分组tibbles的方法。语法:
libary(collapse)
fmode(x, g = NULL, w = NULL, ...)
其中x可以是上述对象之一,g提供一个可选的分组向量或分组向量列表(用于分组模式计算,也在c++中执行),w(可选)提供一个数值权重向量。在分组tibble方法中,没有g参数,您可以执行data %>% group_by(idvar) %>% fmode。
基于@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的,各种输出选项的条件只导致很小的开销: