2013-09-02 16 views
5

Ich möchte die häufigste Kombination von Werten in einem dat.frame finden.Finde die häufigste Kombination von Werten in einem data.frame

Hier einige Beispieldaten:

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

In diesem Beispiel ist das Ergebnis, das ich stehe auf die Kombination von Alter = 55, Geschlecht = 1 und bmi = 25, denn das ist die häufigste Kombination aus Spalten Werte.

Meine realen Daten haben etwa 30000 Zeilen und 20 Spalten. Was wäre ein effizienter Weg, um die häufigste Kombination dieser 20 Werte unter den 30000 Beobachtungen zu finden?

Vielen Dank!

Antwort

7

Hier ist ein Ansatz mit 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 

Und ein Ansatz mit Basis R:

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

Ich weiß nicht, wie gut einem dieser Skala allerdings, insbesondere wenn die Anzahl der Kombinationen wird groß sein. Also, test zurück und berichte!


ersetzen x$Freq == max(x$Freq) mit which.max(x$Freq) und N == max(N) mit which.max(N), wenn Sie in einer Zeile der Ergebnisse wirklich nur interessiert sind.

+0

Danke für die Erklärung! Der data.table-Ansatz funktioniert perfekt und ist sehr schnell (0,31 Sekunden für meine eigenen Daten von 30000 * 20), der Basis-R-Ansatz funktioniert jedoch nicht mit meinen eigenen Daten, da die Anzahl der Kombinationen tatsächlich zu groß für die Tabelle ist(). – Rob

+0

Probieren Sie einfach die 'dt [, .N, durch = Taste (dt)] [N == welche max (N)]' Sie vorgeschlagen, nur eine Zeile zu bekommen, aber das gibt mir das gleiche Ergebnis als 'dt [,. N, by = Taste (dt)] [N == max (N)] '... Gibt es Vorschläge, wie man nur eine Zeile mit der gebräuchlichsten Wertekombination erhält? – Rob

+0

@Rob, Es sollte 'dt [, .N, durch = Schlüssel (dt)] sein [which.max (N)]'. – A5C1D2H2I1M1N2O1R2T1

1

So etwas?

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

mit while (vielleicht zeitaufwendig)

Hier ist eine andere data.frame mit mehr als 1 Fall dupliziert

> 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

Die schnelle und schmutzige Lösung. Ich bin sicher, dass es einen schickeren Weg dazu gibt, mit dem plyr Paket oder ähnlichem.

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

'Tabelle (do.call (einfügen, dat))' funktioniert auch. Nicht sicher, wie es Geschwindigkeit mit 'apply (...)' vergleicht – A5C1D2H2I1M1N2O1R2T1

+0

Danke, funktioniert perfekt! do.call scheint etwas schneller zu sein als die apply-Methode (2.00 sec vs. 2.58 sec). – Rob

+0

Das liegt wohl daran, dass in meiner 'apply' Lösung' paste' in jeder Zeile aufgerufen wird, aber in der 'do.call' Lösung nur einmal aufgerufen wird. Ich bin froh, dass Sie sich auf AnandaMahtos Antwort festgelegt haben, es ist definitiv der richtige Weg. – Backlin

Verwandte Themen