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

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

Ответы [ 30 ]

6 голосов
/ 13 сентября 2016

Этот хак должен работать нормально. Дает вам значение, а также счетчик режима:

Mode <- function(x){
a = table(x) # x is a vector
return(a[which.max(a)])
}
5 голосов
/ 29 июня 2016

На основе функции @ Chris для расчета режима или связанных показателей, однако с использованием метода Кена Уильямса для расчета частот. Это обеспечивает исправление для случая отсутствия режимов вообще (все элементы одинаково часты), а также для некоторых более читаемых 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'")
}

Так как он использует метод Кена для расчета частот, производительность также оптимизируется, используя пост AkselA, я сравнил некоторые из предыдущих ответов, чтобы показать, насколько моя функция близка к производительности Кена, с условностями для различных вариантов вывода, вызывающими только незначительные накладные расходы: Comparison of Mode functions

3 голосов
/ 07 февраля 2014

Это работает довольно хорошо

> a<-c(1,1,2,2,3,3,4,4,5)
> names(table(a))[table(a)==max(table(a))]
3 голосов
/ 06 сентября 2015

Вот функция для поиска режима:

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)
}
3 голосов
/ 30 марта 2010

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
Это, кажется, подтверждает, что (по крайней мере, на момент написания этого урока) в R нет функции mode (ну ... mode (), как вы выяснили, используется для определения типа переменных).

2 голосов
/ 05 сентября 2018

Режим не может быть полезным в любых ситуациях. Таким образом, функция должна решать эту ситуацию. Попробуйте следующую функцию.

Mode <- function(v) {
  # checking unique numbers in the input
  uniqv <- unique(v)
  # frquency of most occured value in the input data
  m1 <- max(tabulate(match(v, uniqv)))
  n <- length(tabulate(match(v, uniqv)))
  # if all elements are same
  same_val_check <- all(diff(v) == 0)
  if(same_val_check == F){
    # frquency of second most occured value in the input data
    m2 <- sort(tabulate(match(v, uniqv)),partial=n-1)[n-1]
    if (m1 != m2) {
      # Returning the most repeated value
      mode <- uniqv[which.max(tabulate(match(v, uniqv)))]
    } else{
      mode <- "Two or more values have same frequency. So mode can't be calculated."
    }
  } else {
    # if all elements are same
    mode <- unique(v)
  }
  return(mode)
}

Выход

x1 <- c(1,2,3,3,3,4,5)
Mode(x1)
# [1] 3

x2 <- c(1,2,3,4,5)
Mode(x2)
# [1] "Two or more varibles have same frequency. So mode can't be calculated."

x3 <- c(1,1,2,3,3,4,5)
Mode(x3)
# [1] "Two or more values have same frequency. So mode can't be calculated."
2 голосов
/ 24 апреля 2018

Существует несколько решений для этого. Я проверил первый и после этого написал свой. Разместите здесь, если это кому-нибудь поможет:

Mode <- function(x){
  y <- data.frame(table(x))
  y[y$Freq == max(y$Freq),1]
}

Давайте проверим это на нескольких примерах. Я беру набор данных iris. Давайте проверим числовые данные

> Mode(iris$Sepal.Length)
[1] 5

, который вы можете проверить, верен.

Теперь единственное нечисловое поле в наборе данных iris (Виды) не имеет режима. Давайте проверим на нашем собственном примере

> test <- c("red","red","green","blue","red")
> Mode(test)
[1] red

EDIT

Как уже упоминалось в комментариях, пользователь может захотеть сохранить тип ввода. В этом случае функцию режима можно изменить на:

Mode <- function(x){
  y <- data.frame(table(x))
  z <- y[y$Freq == max(y$Freq),1]
  as(as.character(z),class(x))
}

Последняя строка функции просто приводит окончательное значение режима к типу исходного ввода.

2 голосов
/ 21 февраля 2017

Ниже приведен код, который можно использовать для нахождения режима векторной переменной в R.

a <- table([vector])

names(a[a==max(a)])
2 голосов
/ 27 мая 2016

Я просматривал все эти варианты и начал задумываться об их относительных характеристиках и характеристиках, поэтому я провел несколько тестов. В случае, если кому-то еще интересно то же самое, я поделюсь своими результатами здесь.

Не желая беспокоиться обо всех функциях, опубликованных здесь, я решил сосредоточиться на выборке, основанной на нескольких критериях: функция должна работать как на символьном, факторном, так и на логическом и числовом векторах, она должна иметь дело с NA и другими проблемными значения соответственно, и выходные данные должны быть «разумными», то есть не иметь числовых значений в виде символов или других подобных глупостей.

Я также добавил собственную функцию, основанную на той же идее rle, что и у 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

В итоге я запустил пять функций на двух наборах тестовых данных через microbenchmark. Названия функций относятся к их авторам:

enter image description here

Функция Криса была установлена ​​на method="modes" и na.rm=TRUE по умолчанию, чтобы сделать ее более сопоставимой, но помимо этого функции использовались, как представлено здесь их авторами.

В зависимости от скорости, версия Kens выигрывает легко, но она также является единственной, которая сообщает только об одном режиме, независимо от того, сколько на самом деле их существует. Как это часто бывает, существует компромисс между скоростью и универсальностью. В method="mode" версия Криса вернет значение, если есть один режим, иначе NA. Я думаю, что это приятное прикосновение. Я также думаю, что интересно, как на некоторые функции влияет увеличение числа уникальных значений, в то время как на другие это не так сильно. Я не изучил код подробно, чтобы выяснить, почему это так, кроме устранения логической / числовой причины.

2 голосов
/ 24 декабря 2014

Хотя мне нравится простая функция Кена Уильямса, я бы хотел получить несколько режимов, если они существуют. Имея это в виду, я использую следующую функцию, которая возвращает список режимов, если несколько или один.

rmode <- function(x) {
  x <- sort(x)  
  u <- unique(x)
  y <- lapply(u, function(y) length(x[x==y]))
  u[which( unlist(y) == max(unlist(y)) )]
} 
...