Existe uma function incorporada para encontrar o modo?

Em R, mean() e median() são funções padrão que fazem o que você espera. mode() informa o modo de armazenamento interno do object, não o valor que ocorre mais em seu argumento. Mas existe uma function de biblioteca padrão que implementa o modo estatístico para um vetor (ou lista)?

Mais uma solução, que funciona para dados numéricos e de caractere / fator:

 Mode < - function(x) { ux <- unique(x) ux[which.max(tabulate(match(x, ux)))] } 

Na minha pequena máquina dinky, isso pode gerar e encontrar o modo de um vetor inteiro de 10M em cerca de meio segundo.

Existe um modo de pacote que fornece estimadores do modo de dados unimodais univodais (e às vezes multimodais) e valores dos modos de distribuições de probabilidade usuais.

 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") 

Para mais informações veja esta página

achei isso na lista de discussão, espero que seja útil. É também o que eu estava pensando de qualquer maneira. Você vai querer tabela () os dados, classificar e, em seguida, escolher o primeiro nome. É hackish, mas deve funcionar.

 names(sort(-table(x)))[1] 

Eu achei o post Ken Williams acima para ser ótimo, adicionei algumas linhas para explicar os valores de NA e fiz disso uma function para facilitar.

 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)))]) } 

Uma maneira rápida e suja de estimar o modo de um vetor de números que você acredita vir de uma distribuição univariada contínua (por exemplo, uma distribuição normal) é definir e usar a seguinte function:

 estimate_mode < - function(x) { d <- density(x) d$x[which.max(d$y)] } 

Então, para obter a estimativa de modo:

 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 

A seguinte function vem em três formas:

method = “mode” [default]: calcula o modo para um vetor unimodal, senão retorna um NA
method = “nmodes”: calcula o número de modos no vetor
method = “modes”: lista todos os modos para um vetor unimodal ou polimodal

 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() } 

Aqui, outra solução:

 freq < - tapply(mySamples,mySamples,length) #or freq <- table(mySamples) as.numeric(names(freq)[which.max(freq)]) 

Eu não posso votar ainda, mas a resposta de Rasmus Bååth é o que eu estava procurando. No entanto, gostaria de modificá-lo um pouco permitindo contrain a distribuição, por exemplo, fro valores apenas entre 0 e 1.

 estimate_mode < - function(x,from=min(x), to=max(x)) { d <- density(x, from=from, to=to) d$x[which.max(d$y)] } 

Estamos cientes de que você pode não querer restringir sua distribuição e, em seguida, definir de = - "GRANDE NÚMERO" para = "GRANDE NÚMERO"

Eu escrevi o seguinte código para gerar o modo.

 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))) } 

Vamos tentar:

 MODE(mtcars) MODE(CO2) MODE(ToothGrowth) MODE(InsectSprays) 

Uma pequena modificação na resposta de Ken Williams, adicionando parâmetros opcionais na.rm e return_multiple .

Ao contrário das respostas que dependem de names() , essa resposta mantém o tipo de dados x nos valores retornados.

 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]) } 

Para mostrar, funciona com os parâmetros opcionais e mantém o tipo de dados:

 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" 

Graças a @Frank por simplificação.

Este hack deve funcionar bem. Dá-lhe o valor, bem como a contagem do modo:

 Mode < - function(x){ a = table(x) # x is a vector return(a[which.max(a)]) } 

Baseado na function do @ Chris para calcular o modo ou métricas relacionadas, no entanto, usando o método de Ken Williams para calcular freqüências. Este fornece uma correção para o caso de nenhum modo (todos os elementos igualmente freqüentes) e alguns nomes de method mais legíveis.

 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'") } 

Como ele usa o método de Ken para calcular as frequências, o desempenho também é otimizado, usando o post de AkselA eu comparei algumas das respostas anteriores para mostrar como minha function está próxima da performance de Ken, com os condicionais para as várias opções de saída causando apenas uma pequena sobrecarga: Comparação de funções do modo

R tem tantos pacotes complementares que alguns deles podem fornecer o modo [estatístico] de uma lista numérica / série / vetor.

No entanto, a biblioteca padrão do R em si não parece ter um método embutido! Uma maneira de contornar isso é usar algumas construções como as seguintes (e transformar isso em uma function se você usar com freqüência …):

 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 

Para uma lista de amostras maior, deve-se considerar o uso de uma variável temporária para o valor max (tabSmpl) (não sei se R otimizaria isso automaticamente)

Referência: consulte “Como sobre mediana e modo?” nesta lição do KickStarting R
Isto parece confirmar que (pelo menos a partir da redação desta lição) não existe uma function de modo em R (bem … mode () como você descobriu é usado para declarar o tipo de variables).

Aqui está uma function para encontrar o modo:

 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) } 

Isso funciona muito bem

 > a< -c(1,1,2,2,3,3,4,4,5) > names(table(a))[table(a)==max(table(a))] 

Embora eu goste da function simples de Ken Williams, gostaria de recuperar os vários modos se eles existirem. Com isso em mente, utilizo a seguinte function que retorna uma lista dos modos, se múltipla ou única.

 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)) )] } 

Eu estava olhando através de todas essas opções e comecei a me perguntar sobre suas características e performances relativas, então fiz alguns testes. Caso alguém mais esteja curioso sobre o mesmo, estou compartilhando meus resultados aqui.

Não querendo se preocupar com todas as funções postadas aqui, optei por focar em uma amostra baseada em alguns critérios: a function deve funcionar tanto em vetores de caractere, fator, lógicos e numéricos, deve lidar com NAs e outros valores problemáticos apropriadamente, e a saída deve ser “sensata”, isto é, nenhum numérico como caractere ou outro tipo de tolice.

Eu também adicionei uma function minha, que é baseada na mesma idéia que a de chrispy, exceto adaptada para uso mais geral:

 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 

Acabei executando cinco funções, em dois conjuntos de dados de teste, através do microbenchmark . Os nomes das funções referem-se aos seus respectivos autores:

insira a descrição da imagem aqui

A function de Chris foi definida para method="modes" e na.rm=TRUE por padrão para torná-la mais comparável, mas outras que as funções foram usadas como apresentadas aqui por seus autores.

Em questão de velocidade, a versão Kens ganha com facilidade, mas também é a única que reporta apenas um modo, não importa quantos realmente existam. Como é frequentemente o caso, há um trade-off entre velocidade e versatilidade. Em method="mode" , a versão de Chris retornará um valor se houver um modo, ou seja, NA. Eu acho que é um toque legal. Eu também acho interessante como algumas das funções são afetadas por um número maior de valores únicos, enquanto outras não são tão grandes. Eu não estudei o código em detalhes para descobrir por que isso é, além de eliminar lógica / numérica como a causa.

Existem várias soluções fornecidas para este. Eu verifiquei o primeiro e depois disso escrevi o meu próprio. Postando aqui se ajudar alguém:

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

Vamos testá-lo com alguns exemplos. Eu estou tomando o dataset da iris . Vamos testar com dados numéricos

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

que você pode verificar está correto.

Agora, o único campo não numérico no dataset da íris (Espécies) não possui um modo. Vamos testar com nosso próprio exemplo

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

EDITAR

Conforme mencionado nos comentários, o usuário pode querer preservar o tipo de input. Nesse caso, a function de modo pode ser modificada para:

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

A última linha da function simplesmente coage o valor do modo final para o tipo da input original.

Outra opção simples que dá todos os valores ordenados por frequência é usar rle :

 df = as.data.frame(unclass(rle(sort(mySamples)))) df = df[order(-df$lengths),] head(df) 

Eu usaria a function density () para identificar um máximo suavizado de uma distribuição (possivelmente contínua):

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

onde x é a coleta de dados. Preste atenção ao parâmetro de ajuste da function de densidade que regula a suavização.

Outra solução possível:

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

Uso:

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

Saída:

  user system elapsed 0.32 0.00 0.31 

Desculpe, eu posso levar isso muito simples, mas isso não funciona? (em 1,3 segundos para valores de 1E6 na minha máquina):

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

Você apenas tem que replace o "round (rnorm (1e6), 2)" com o seu vetor.

Você também pode calcular o número de vezes que uma ocorrência aconteceu no seu conjunto e encontrar o número máximo. por exemplo

 > 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 > 

Poderia tentar a seguinte function:

  1. transformar valores numéricos em fator
  2. use summary () para ganhar a tabela de freqüência
  3. modo de retorno o índice cuja freqüência é o maior
  4. Transformar fator de volta para numérico mesmo que haja mais de 1 modo, esta function funciona bem!
 mode < - function(x){ y <- as.factor(x) freq <- summary(y) mode <- names(freq)[freq[names(freq)] == max(freq)] as.numeric(mode) } 

Modo de cálculo é principalmente em caso de variável de fator, então podemos usar

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

HouseVotes84 é o dataset disponível no pacote ‘mlbench’.

Isso dará o valor máximo do label. é mais fácil de usar por funções inerentes sem function de escrita.

Abaixo está o código que pode ser usado para encontrar o modo de uma variável vetorial em R.

 a < - table([vector]) names(a[a==max(a)]) 

Aqui está a minha versão, incluindo a fração. Devo dizer que vocês me deram novas soluções simples e inteligentes aqui. Muito obrigado!

 get_mode < - function(v) { mode <- table(v) %>% as_data_frame() %>% mutate(frac = n/sum(n)) %>% filter(n == max(n)) return(list("mode_var" = mode$v, "n" = mode$n, "var_frac" = mode$frac)) } get_mode(c(1,1,1,1,1,1,1,1,1,2,2,2,22,2,2,2,2,3234,3,4,545,343,56,676,76,764565,67,676,69,879,8978,9784,765,342,5236,43756,76,6,546)) $mode_var [1] "1" $n [1] 9 $var_frac [1] 0.2307692 

Uma maneira fácil de calcular o MODO de um vetor ‘v’ contendo valores discretos é:

 names(sort(table(v)))[length(sort(table(v)))]