在R中,mean()和median()是标准函数,它们执行您所期望的功能。Mode()告诉您对象的内部存储模式,而不是参数中出现次数最多的值。但是是否存在一个标准库函数来实现向量(或列表)的统计模式?
当前回答
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()用于断言变量的类型)。
其他回答
下面是一个查找模式的函数:
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)
}
在r邮件列表中发现了这个,希望对你有帮助。我也是这么想的。您将希望table()数据,排序,然后选择第一个名称。这有点粗俗,但应该有用。
names(sort(-table(x)))[1]
对此有多种解决方案。我检查了第一个,然后写了我自己的。把它贴在这里,如果它能帮助到任何人:
Mode <- function(x){
y <- data.frame(table(x))
y[y$Freq == max(y$Freq),1]
}
让我们用几个例子来测试一下。我正在取虹膜数据集。让我们用数值数据进行测试
> Mode(iris$Sepal.Length)
[1] 5
你可以验证这是正确的。
现在虹膜数据集中唯一的非数字字段(Species)没有模式。让我们用我们自己的例子进行测试
> test <- c("red","red","green","blue","red")
> Mode(test)
[1] red
EDIT
正如注释中提到的,用户可能希望保留输入类型。在这种情况下,mode函数可以修改为:
Mode <- function(x){
y <- data.frame(table(x))
z <- y[y$Freq == max(y$Freq),1]
as(as.character(z),class(x))
}
函数的最后一行只是将最终的模式值强制为原始输入的类型。
基于@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的,各种输出选项的条件只导致很小的开销:
这里有另一个解决方案:
freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])
推荐文章
- 为什么使用purrr::map而不是lapply?
- 如何在data.table中按名称删除列?
- 将data.frame从宽格式调整为长格式
- 计算移动平均线
- 在R中同一行打印字符串和变量内容
- 使用pandoc从Markdown转换为PDF时设置空白大小
- ggplot2折线图给出“geom_path:每组只包含一个观测值。你需要调整群体审美吗?”
- np.mean() vs np.average()在Python NumPy?
- 导入文本文件为单字符字符串
- 移除jupyter笔记本上的内核
- 提取一个dplyr tbl列作为向量
- 如何在R中绘制两个直方图?
- 显示/打印tibble的所有行(tbl_df)
- 用MySQL计算中位数的简单方法
- 我如何做一个数据帧的列表?