2013-09-02 14 views
5

Chciałbym znaleźć najczęstszą kombinację wartości w data.frame.Znajdź najczęstszą kombinację wartości w data.frame

Oto kilka przykładów danych:

dat <- data.frame(age=c(50,55,60,50,55),sex=c(1,1,1,0,1),bmi=c(20,25,30,20,25)) 

W tym przykładzie wynik szukam jest kombinacją wieku = 55, seks = 1 i BMI = 25, ponieważ jest najczęstszą kombinacją kolumny wartości.

Moje prawdziwe dane mają około 30000 wierszy i 20 kolumn. Jaki byłby skuteczny sposób na znalezienie najczęstszej kombinacji tych 20 wartości spośród 30000 obserwacji?

Wielkie dzięki!

Odpowiedz

7

Oto podejście z data.table:

dt <- data.table(dat) 
setkeyv(dt, names(dt)) 
dt[, .N, by = key(dt)] 
dt[, .N, by = key(dt)][N == max(N)] 
# age sex bmi N 
# 1: 55 1 25 2 

oraz podejścia z bazy R:

x <- data.frame(table(dat)) 
x[x$Freq == max(x$Freq), ] 
# age sex bmi Freq 
# 11 55 1 25 2 

nie wiem jak dobrze albo z tymi skali chociaż, szczególnie jeśli liczba kombinacji będzie duża. Tak, przetestuj i zgłoś!


Wymień x$Freq == max(x$Freq) z which.max(x$Freq) i N == max(N) z which.max(N) jeśli jesteś naprawdę zainteresowany w jednym rzędzie wyników.

+0

Dzięki za wyjaśnienie! Podejście data.table działa doskonale i jest bardzo szybkie (0,31 s na moich własnych danych 30000 * 20), jednak podstawowe podejście R nie działa na moich własnych danych, ponieważ liczba kombinacji jest rzeczywiście zbyt duża dla tabeli(). – Rob

+0

Po prostu wypróbowałem 'dt [, .N, przez = klucz (dt)] [N == który max (N)]' zasugerowałeś, aby uzyskać tylko jeden wiersz, ale to daje mi ten sam rezultat als 'dt [,. N, przez = klucz (dt)] [N == maks. (N)] '... Jakieś sugestie, jak uzyskać tylko jeden wiersz z najczęstszą kombinacją wartości? – Rob

+0

@Rob, Powinien to być 'dt [, .N, przez = klucz (dt)] [który.max (N)]'. – A5C1D2H2I1M1N2O1R2T1

1

Coś takiego?

> dat[duplicated(dat), ] 
    age sex bmi 
5 55 1 25 

użyciu while (może czasochłonne)

Oto kolejny data.frame z więcej niż 1 przypadku powielane

> dat <- data.frame(age=c(50,55,60,50,55, 55, 60), 
        sex=c(1,1,1,0,1, 1,1), 
        bmi=c(20,25,30,20,25, 25,30)) 
> dat[duplicated(dat), ] # see data.frame 
     age sex bmi 
    5 55 1 25 
    6 55 1 25 
    7 60 1 30 


# finding the most repeated item 
> while(any(duplicated(dat))){ 
    dat <- dat[duplicated(dat), ] 
    #print(dat) 
} 

> print(dat) 
    age sex bmi 
6 55 1 25 
1

Szybki i brudny roztwór. Jestem pewien, że jest na to lepszy sposób, z pakietem plyr lub podobnym.

> (tab <- table(apply(dat, 1, paste, collapse=", "))) 
50, 0, 20 50, 1, 20 55, 1, 25 60, 1, 30 
     1   1   2   1 

> names(which.max(tab)) 
[1] "55, 1, 25" 
+0

'table (do.call (paste, dat))' również działa. Nie wiem, w jaki sposób porównuje szybkość z 'apply (...)' – A5C1D2H2I1M1N2O1R2T1

+0

Dzięki, działa idealnie! Komenda do.call wydaje się być nieco szybsza od metody stosowanej (2,00 s vs 2,58 s). – Rob

+0

Jest to prawdopodobnie spowodowane tym, że w moim rozwiązaniu 'apply',' paste' jest wywoływany w każdym wierszu, ale w rozwiązaniu 'do.call' jest on wywoływany tylko raz. Cieszę się, że zdecydowałeś się na odpowiedź @ AnandaMahto, ale to zdecydowanie jest droga. – Backlin

Powiązane problemy