Есть ли встроенная функция для нахождения режима? - PullRequest
356 голосов
/ 30 марта 2010

В R * mean() и median() - это стандартные функции, которые выполняют то, что вы ожидаете. mode() сообщает вам режим внутреннего хранения объекта, а не значение, которое встречается чаще всего в его аргументе. Но есть ли стандартная библиотечная функция, которая реализует статистический режим для вектора (или списка)?

Ответы [ 30 ]

1 голос
/ 26 марта 2019

Я считаю, что ваши наблюдения составляют классы из Действительные числа , и вы ожидаете, что режим будет равен 2,5, когда ваши наблюдения составляют 2, 2, 3 и 3, тогда вы можете оценить режим с помощью mode = l1 + i * (f1-f0) / (2f1 - f0 - f2), где l1 .. нижний предел наиболее частого класса, f1 .. частота наиболее частого класса, f0 ..частота классов перед самым частым классом, f2 .. частота классов после самого частого класса и i .. Интервал класса, как указано, например в 1 , 2 , 3 :

#Small Example
x <- c(2,2,3,3) #Observations
i <- 1          #Class interval

z <- hist(x, breaks = seq(min(x)-1.5*i, max(x)+1.5*i, i), plot=F) #Calculate frequency of classes
mf <- which.max(z$counts)   #index of most frequent class
zc <- z$counts
z$breaks[mf] + i * (zc[mf] - zc[mf-1]) / (2*zc[mf] - zc[mf-1] - zc[mf+1])  #gives you the mode of 2.5


#Larger Example
set.seed(0)
i <- 5          #Class interval
x <- round(rnorm(100,mean=100,sd=10)/i)*i #Observations

z <- hist(x, breaks = seq(min(x)-1.5*i, max(x)+1.5*i, i), plot=F)
mf <- which.max(z$counts)
zc <- z$counts
z$breaks[mf] + i * (zc[mf] - zc[mf-1]) / (2*zc[mf] - zc[mf-1] - zc[mf+1])  #gives you the mode of 99.5

Если вам нужен самый частый уровень и у вас есть более одного наиболее частого уровня, вы можете получить все из них, например. с:

x <- c(2,2,3,5,5)
names(which(max(table(x))==table(x)))
#"2" "5"
1 голос
/ 14 ноября 2018

Это основано на ответе jprockbelly, добавив ускорение для очень коротких векторов. Это полезно при применении режима к 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)))]
}
1 голос
/ 04 декабря 2012

Другая простая опция, которая дает все значения, упорядоченные по частоте, - это использование rle:

df = as.data.frame(unclass(rle(sort(mySamples))))
df = df[order(-df$lengths),]
head(df)
1 голос
/ 16 декабря 2015

Другое возможное решение:

Mode <- function(x) {
    if (is.numeric(x)) {
        x_table <- table(x)
        return(as.numeric(names(x_table)[which.max(x_table)]))
    }
}

Использование:

set.seed(100)
v <- sample(x = 1:100, size = 1000000, replace = TRUE)
system.time(Mode(v))

Выход:

   user  system elapsed 
   0.32    0.00    0.31 
1 голос
/ 02 мая 2014

Я бы использовал функцию плотности () для определения сглаженного максимума (возможно, непрерывного) распределения:

function(x) density(x, 2)$x[density(x, 2)$y == max(density(x, 2)$y)]

где x - сбор данных. Обратите внимание на параметр Adjust функции плотности, который регулирует сглаживание.

0 голосов
/ 21 сентября 2016

Режим расчета в основном для факторной переменной, тогда мы можем использовать

labels(table(HouseVotes84$V1)[as.numeric(labels(max(table(HouseVotes84$V1))))])

HouseVotes84 - это набор данных, доступный в пакете 'mlbench'.

это даст максимальное значение метки. это проще использовать встроенными функциями без написания функции.

0 голосов
/ 10 апреля 2013

Извините, я могу принять это слишком просто, но разве это не делает работу? (через 1,3 секунды для значений 1E6 на моем компьютере):

t0 <- Sys.time()
summary(as.factor(round(rnorm(1e6), 2)))[1]
Sys.time()-t0

Вам просто нужно заменить "round (rnorm (1e6), 2)" на ваш вектор.

0 голосов
/ 27 августа 2016

Простой способ рассчитать MODE вектора 'v', содержащего дискретные значения:

names(sort(table(v)))[length(sort(table(v)))]
0 голосов
/ 03 декабря 2013

Вы также можете рассчитать количество случаев, когда экземпляр произошел в вашем наборе, и найти максимальное число. например,

> temp <- table(as.vector(x))
> names (temp)[temp==max(temp)]
[1] "1"
> as.data.frame(table(x))
r5050 Freq
1     0   13
2     1   15
3     2    6
> 
0 голосов
/ 05 апреля 2014

Можно попробовать следующую функцию:

  1. преобразование числовых значений в коэффициент
  2. используйте summary (), чтобы получить таблицу частот
  3. режим возврата индекса, частота которого самая большая
  4. преобразование коэффициента обратно в числовое значение, даже если имеется более 1 режима, эта функция работает хорошо!
mode <- function(x){
  y <- as.factor(x)
  freq <- summary(y)
  mode <- names(freq)[freq[names(freq)] == max(freq)]
  as.numeric(mode)
}
...