2013-11-14 12 views
8

Nadal jestem względnie nowy w R, więc przepraszam z góry, jeśli moje pytanie wydaje się zbyt proste.Jak znaleźć najczęstsze wartości w kilku kolumnach zawierających czynniki

Mój problem jest następujący:

Mam zestaw danych zawierającą kilka zmiennych czynnikiem, który mają te same kategorie. Muszę znaleźć kategorię, która występuje najczęściej dla każdej obserwacji w obrębie zmiennych czynnikowych. W przypadku więzi można wybrać dowolną wartość, chociaż byłoby wspaniale, gdybym mógł mieć nad nią większą kontrolę.

Mój zestaw danych zawiera ponad sto czynników. Jednakże, struktura ta jest mniej więcej tak, że:

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 

Roztwór powinien być zmienny w ramki danych, na przykład, który zawiera var5 Najczęstszym kategorii dla każdego rzędu. może to być czynnik lub wektor numeryczna (w przypadku potrzebne dane, które mają być przekształcany do wektorów numerycznych)

W tym wypadku, że jak do tego rozwiązania:

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

Każda porady będą bardzo doceniane! Z góry dziękuję!

Odpowiedz

13

Coś jak:

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

W przypadku remisu, which.max zajmuje pierwszą wartość max. Od strony which.max pomocy:

określa położenie, to znaczy indeks (pierwszego) minimum lub maksimum wektora numerycznej.

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

dobra robota, czystsza niż moja. Nie zdawałem sobie sprawy, że mogę pominąć wszystkie konwersje, niepubliczne itp. –

+0

Dziękuję bardzo za to rozwiązanie. Po prostu wypróbowałem to na własnych danych i działa idealnie! Czy mógłbyś mi tylko wyjaśnić, w jaki sposób ta metoda rozwiązuje więzi? Dzięki! – ZMacarozzi

+0

Edytowałem swoją odpowiedź, aby zilustrować sprawę za pomocą remisu. To dobry nawyk, aby nauczyć się korzystać ze stron pomocy. Cieszę się, że moje rozwiązanie działa dla ciebie. – Chargaff

0

Jeśli dane jest dość duży może warto rozważyć przy użyciu pakietu data.table.

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

rozwiązanie Chargaff jest prosty i działa dobrze w niektórych przypadkach. Możesz uzyskać niewielką poprawę wydajności (~ 20%) za pomocą data.table.

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