Gibt es eine eingebaute function, um den Modus zu finden?

In R sind mean() und median() Standardfunktionen, die das tun, was Sie erwarten. mode() teilt Ihnen den internen Speichermodus des Objekts mit, nicht den Wert, der in seinem Argument am häufigsten vorkommt. Aber gibt es eine Standardbibliotheksfunktion, die den statistischen Modus für einen Vektor (oder eine Liste) implementiert?

Solutions Collecting From Web of "Gibt es eine eingebaute function, um den Modus zu finden?"

Eine weitere Lösung, die sowohl für numerische als auch für Zeichen- / Faktordaten funktioniert:

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

Auf meiner kleinen, kleinen Maschine kann das den Modus eines 10M-Integer-Vektors in ungefähr einer halben Sekunde erzeugen und finden.

Es gibt Package- modeest , die Schätzer für den Modus der univariaten unimodalen (und manchmal multimodalen) Daten und Werte der Modi der üblichen Wahrscheinlichkeitsverteilungen liefern.

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

Weitere Informationen finden Sie auf dieser Seite

fand das auf der r Mailingliste, hoffe es ist hilfreich. Darüber habe ich auch nachgedacht. Sie sollten die Daten in Tabelle () einfügen, sortieren und dann den Vornamen auswählen. Es ist hackish, sollte aber funktionieren.

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

Ich fand Ken Williams Post oben großartig, ich fügte ein paar Zeilen hinzu, um NA-Werte zu berücksichtigen, und machte es zu einer function für Leichtigkeit.

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

Eine schnelle und schmutzige Methode zur Schätzung des Modus eines Zahlenvektors, von dem Sie glauben, dass er aus einer kontinuierlichen univariaten Verteilung (z. B. einer Normalverteilung) stammt, definiert und verwendet die folgende function:

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

Dann um die Modusschätzung zu erhalten:

 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 

Die folgende function gibt es in drei Formen:

method = “mode” [default]: berechnet den Modus für einen unimodalen Vektor, sonst gibt er eine NA zurück
method = “nmodes”: berechnet die Anzahl der Modi im Vektor
method = “modes”: listet alle Modi für einen unimodalen oder polymodalen Vektor auf

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

Hier, eine andere Lösung:

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

Ich kann noch nicht wählen, aber Rasmus Bååths Antwort ist, wonach ich gesucht habe. Ich würde es jedoch etwas modifizieren, um z. B. Werte zwischen 0 und 1 entgegenzusetzen.

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

Wir sind uns bewusst, dass Sie Ihre Distribution möglicherweise nicht beschränken möchten, und setzen Sie dann von = - "BIG NUMBER" auf = "BIG NUMBER".

Ich habe den folgenden Code geschrieben, um den Modus zu generieren.

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

Lass es uns versuchen:

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

Eine kleine Änderung an Ken Williams ‘Antwort, die optionalen Parameter na.rm und return_multiple .

Im Gegensatz zu den Antworten, die auf names() basieren, behält diese Antwort den Datentyp von x in den zurückgegebenen Werten bei.

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

Um es zu zeigen, arbeitet es mit den optionalen Parametern und pflegt den Datentyp:

 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" 

Danke an @Frank für die Vereinfachung.

Dieser Hack sollte gut funktionieren. Gibt Ihnen den Wert sowie die Anzahl der Modi:

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

Basierend auf der @ Chris-function zur Berechnung des Modus oder der zugehörigen Metriken, jedoch unter Verwendung der Methode von Ken Williams zur Berechnung von Frequenzen. Dieser bietet eine Korrektur für den Fall, dass keine Modi vorhanden sind (alle Elemente sind gleich häufig) und einige besser lesbare 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'") } 

Da die Kens-Methode verwendet wird, um Frequenzen zu berechnen, wird auch die performance optimiert. Mithilfe von AkselAs Post habe ich einige der vorherigen Antworten verglichen, um zu zeigen, wie meine function der performance von Kens nahe kommt, wobei die Bedingungen für die verschiedenen Ausgabeoptionen nur geringen Overhead verursachen: Vergleich der Modusfunktionen

R hat so viele Add-on-Pakete, dass einige von ihnen den [statistischen] Modus einer numerischen Liste / Reihe / Vektor bereitstellen können.

Die Standardbibliothek von R selbst scheint jedoch keine so eingebaute Methode zu haben! Eine Möglichkeit, dies zu umgehen, besteht darin, ein Konstrukt wie das folgende zu verwenden (und dies zu einer function zu machen, wenn Sie oft … verwenden):

 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 

Für eine größere Probenliste sollte man eine temporäre Variable für den max (tabSmpl) Wert verwenden (ich weiß nicht, dass R dies automatisch optimieren würde)

Referenz: siehe “Wie wäre es mit Median und Modus?” in dieser KickStarting R Lektion
Dies scheint zu bestätigen, dass es (zumindest zum Zeitpunkt des Schreibens dieser Lektion) keine Modusfunktion in R (well … mode () gibt, wie Sie herausgefunden haben, um den Typ der Variablen zu bestätigen).

Hier ist eine function, um den Modus zu finden:

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

Das funktioniert ganz gut

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

Während ich Ken Williams einfache function mag, möchte ich die verschiedenen Modi abrufen, wenn sie existieren. In diesem Sinne verwende ich die folgende function, die eine Liste der Modi zurückgibt, wenn mehrere oder die einzige.

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

Ich habe alle diese Optionen durchgesehen und angefangen, mich über ihre relativen Eigenschaften und performanceen zu wundern, also habe ich ein paar Tests gemacht. Falls jemand anders neugierig ist, teile ich hier meine Ergebnisse.

Da ich mich nicht um alle hier aufgeführten functionen kümmern möchte, habe ich mich auf ein Beispiel basierend auf einigen Kriterien konzentriert: Die function sollte sowohl auf Zeichen-, Faktor-, logischen und numerischen Vektoren arbeiten, sie sollte angemessen mit NAs und anderen problematischen Werten umgehen. und Ausgabe sollte “vernünftig” sein, dh keine Zahlen als Zeichen oder andere solche Unbequemlichkeit.

Ich fügte auch eine eigene function hinzu, die auf der gleichen Idee wie die von Chrispy basiert, außer dass sie für eine allgemeinere Verwendung angepasst wurde:

 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 

Ich beendete fünf functionen, auf zwei Testdatensätzen, durch microbenchmark . Die functionsnamen beziehen sich auf ihre jeweiligen Autoren:

Bildbeschreibung hier eingeben

Die function von Chris wurde standardmäßig auf method="modes" und na.rm=TRUE gesetzt, um sie vergleichbar zu machen, aber na.rm=TRUE wurden die functionen so verwendet, wie sie hier von ihren Autoren vorgestellt wurden.

In Sachen Geschwindigkeit gewinnt alleine die Kens-Version, aber sie ist auch die Einzige, die nur einen Modus meldet, egal wie viele es sind. Wie es oft der Fall ist, gibt es einen Kompromiss zwischen Geschwindigkeit und Vielseitigkeit. In method="mode" gibt Chris 'Version einen Wert zurück, wenn es einen Modus gibt, sonst NA. Ich denke, das ist eine nette Geste. Ich denke auch, dass es interessant ist, wie einige der functionen durch eine erhöhte Anzahl von einzigartigen Werten beeinflusst werden, während andere nicht annähernd so viel sind. Ich habe den Code nicht im Detail studiert, um herauszufinden, warum das so ist, abgesehen von der Beseitigung von logisch / numerisch als Ursache.

Es gibt mehrere Lösungen für diesen. Ich überprüfte das erste und schrieb danach mein eigenes. Es hier zu posten, wenn es jemandem hilft:

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

Lass es uns mit ein paar Beispielen testen. Ich nehme den iris Datensatz. Lasst uns mit numerischen Daten testen

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

was du verifizieren kannst, ist richtig.

Jetzt hat das einzige nicht-numerische Feld im Iris-Datensatz (Spezies) keinen Modus. Lass uns mit unserem eigenen Beispiel testen

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

BEARBEITEN

Wie in den Kommentaren erwähnt, möchte der Benutzer möglicherweise den Eingabetyp beibehalten. In diesem Fall kann die Modusfunktion wie folgt geändert werden:

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

Die letzte Zeile der function erzwingt lediglich den letzten Moduswert auf den Typ der ursprünglichen Eingabe.

Eine weitere einfache Option, die alle nach Häufigkeit geordneten Werte rle ist die Verwendung von rle :

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

Ich würde die dichte () function verwenden, um ein geglättetes Maximum einer (möglicherweise kontinuierlichen) Verteilung zu identifizieren:

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

wo x ist die Datensammlung. Achten Sie auf den Einstellparameter der Dichtefunktion, die die Glättung regelt.

Eine andere mögliche Lösung:

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

Verwendung:

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

Ausgabe:

  user system elapsed 0.32 0.00 0.31 

Tut mir leid, ich nehme es zu einfach, aber macht das nicht den Job? (in 1,3 Sekunden für 1E6 Werte auf meiner Maschine):

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

Sie müssen nur die "Runde (rnorm (1e6), 2)" mit Ihrem Vektor ersetzen.

Sie können auch berechnen, wie oft eine Instanz in Ihrem Set passiert ist und die maximale Anzahl finden. z.B

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

Könnte die folgende function ausprobieren:

  1. Transformiere numerische Werte in factor
  2. Verwenden Sie summary (), um die Häufigkeitstabelle zu erhalten
  3. return mode der Index, dessen Häufigkeit die größte ist
  4. Umwandeln des Faktors zurück in numerisch, auch wenn es mehr als 1 Modus gibt, funktioniert diese function gut!
 mode < - function(x){ y <- as.factor(x) freq <- summary(y) mode <- names(freq)[freq[names(freq)] == max(freq)] as.numeric(mode) } 

Berechnungsmodus ist meistens im Falle einer Faktorvariablen, die wir verwenden können

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

HouseVotes84 ist im “mlbench” -Paket verfügbar.

es gibt maximalen Label-Wert. es ist einfacher, durch eingebaute functionen selbst ohne Schreibfunktion zu verwenden.

Unten ist der Code, der verwendet werden kann, um den Modus einer Vektorvariablen in R zu finden.

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

Hier ist meine Version inklusive der Fraktion. Ich muss sagen, ihr habt mir so viele neue einfache und schlaue Lösungen gegeben. Danke vielmals!

 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 

Eine einfache Methode zur Berechnung von MODE eines Vektors ‘v’ mit diskreten Werten ist:

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