2013-11-14 30 views
8

Ich bin noch relativ neu zu R, also Entschuldigung im Voraus, wenn meine Frage zu einfach scheint.Wie finde ich die häufigsten Werte über mehrere Spalten mit Faktoren

Mein Problem ist wie folgt:

ich einen Datensatz mit mehreren Faktorvariablen haben, die die gleichen Kategorien haben. Ich muss die Kategorie finden, die am häufigsten für jede Beobachtung über die Faktorvariablen auftritt. Im Falle von Bindungen kann ein beliebiger Wert gewählt werden, obwohl es großartig wäre, wenn ich mehr Kontrolle darüber hätte.

Mein Datensatz enthält über hundert Faktoren. Jedoch ist die Struktur so ähnlich:

id <- 1:3 
var1 <- c("red","yellow","green") 
var2 <- c("red","yellow","green") 
var3 <- c("yellow","orange","green") 
var4 <- c("orange","green","yellow") 
df <- data.frame(cbind(id, var1, var2, var3, var4)) 


> df 
    id var1 var2 var3 var4 
1 1 red red yellow orange 
2 2 yellow yellow orange green 
3 3 green green green yellow 

die Lösung eine Variable innerhalb des Datenrahmens sein sollte, zum Beispiel var5, die die häufigste Kategorie für jede Zeile enthält. Es kann ein Faktor oder ein numerischer Vektor sein (falls die Daten müssen zuerst in numerische Vektoren umgewandelt werden) In diesem Fall

, möchte ich an dieser Lösung haben:

> df$var5 
[1] "red" "yellow" "green" 

Jede Beratung wird sehr geschätzt! Danke im Voraus!

Antwort

13

Etwas wie:

apply(df,1,function(x) names(which.max(table(x)))) 
[1] "red" "yellow" "green" 

Falls es einen Gleichstand, which.max den ersten Maximalwert annimmt. Von der which.max Hilfeseite:

die Position Bestimmt, das heißt Index des (ersten) Minimum oder Maximum eines numerischen Vektors.

Ex:

var4 <- c("yellow","green","yellow") 
df <- data.frame(cbind(id, var1, var2, var3, var4)) 

> df 
    id var1 var2 var3 var4 
1 1 red red yellow yellow 
2 2 yellow yellow orange green 
3 3 green green green yellow 

apply(df,1,function(x) names(which.max(table(x)))) 
[1] "red" "yellow" "green" 
+0

netter Job, sauberer als meins. Hatte nicht realisiert, dass ich alle Conversions, Unlisting usw. überspringen konnte. –

+0

Vielen Dank für diese Lösung. Ich habe es gerade auf meinen eigenen Daten versucht und es funktioniert perfekt! Können Sie, bitte, nur für mich klären, wie löst diese Methode die Bindungen? Vielen Dank! – ZMacarozzi

+0

Ich redigierte meine Antwort, um Fall mit einer Bindung zu veranschaulichen. Es ist eine gute Angewohnheit zu lernen, wie man die Hilfeseiten benutzt. Ich bin froh, dass meine Lösung für Sie funktioniert hat. – Chargaff

0

Wenn Ihre Daten sehr groß ist, dass Sie mit dem data.table Paket vielleicht zu prüfen.

# Generate the data 
nrow <- 10^5 
id <- 1:nrow 
colors <- c("red","yellow","green") 
var1 <- sample(colors, nrow, replace = TRUE) 
var2 <- sample(colors, nrow, replace = TRUE) 
var3 <- sample(colors, nrow, replace = TRUE) 
var4 <- sample(colors, nrow, replace = TRUE) 

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

Chargaffs Lösung ist einfach und funktioniert gut in einigen Fällen. Mit data.table können Sie eine kleine Leistungsverbesserung (~ 20%) erzielen.

df <- data.frame(cbind(id, var1, var2, var3, var4)) 
system.time(apply(df, 1, Mode)) 
# user system elapsed 
# 1.242 0.018 1.264 

library(data.table) 
dt <- data.table(cbind(id, var1, var2, var3, var4)) 
system.time(melt(dt, measure = patterns('var'))[, Mode(value1), by = id]) 
# user system elapsed 
# 1.020 0.012 1.034