2015-01-14 11 views
5

einen Datenrahmen Stellen Sie sich vor:Subsetting auf Zeilenebene, aber Wert muss Spaltenname

set.seed(1234) 
data<-data.frame(id = sample(letters, 26, replace = FALSE), 
         a = sample(1:10,26,replace=T), 
         b = sample(1:10,26,replace=T), 
         c = sample(1:10,26,replace=T)) 

Ich mag, halten für jeden id, die Spaltennamen, in dem die größten Wert liegt. Das Ergebnis, das ich suche, ist ein Datenrahmen mit den Abmessungen 26 x 2 mit einer Spalte für id und Spalte für largest_value_var. Die largest_value_var würde entweder a, b oder c enthalten.

Bisher konnte ich den Variablennamen extrahieren, mit dem der Maximalwert zugeordnet ist, mit diesem:

apply(data[,-1], 1, function(x) c(names(x))[which.max(x)]) 

Aber ich kann nicht das Ergebnis ganz scheinen, ich in ein möchten Dataframe ... Jede Hilfe wird geschätzt.

Antwort

7

Sie können dies relativ einfach mit max.col() tun. Setzen Sie ties.method = "first" (danke akrun), wir erhalten die erste Spalte im Falle einer Krawatte. Hier ist eine Datentabelle Methode:

library(data.table) 
setDT(data)[, names(.SD)[max.col(.SD, "first")], by = id] 

Update: Es scheint, diese Methode wäre effizienter, wenn in der Basis R umgesetzt, wahrscheinlich wegen der as.matrix() Umwandlung in max.col(). Also hier ist ein Weg, um es in der Basis zu erreichen.

cbind(data[1], largest = names(data)[-1][max.col(data[-1], "first")]) 

Danke an Ananda Mahto für den Hinweis auf den Effizienzunterschied.

4

Ich mag @ Richards Verwendung von max.col, aber das erste, was mir in den Sinn kam, war tatsächlich die Daten in eine „saubere“ Form erhalten zuerst, danach die subsetting tun Sie sollte einfach sein wollen:

library(reshape2) 
library(data.table) 
melt(as.data.table(data), id.vars = "id")[, variable[which.max(value)], by = id] 
#  id V1 
# 1: c b 
# 2: p a 
# 3: o c 
# 4: x b 
# 5: s a 
## SNIP ### 
# 21: g a 
# 22: f b 
# 23: t a 
# 24: y a 
# 25: w b 
# 26: v a 
#  id V1 
+0

Ich mochte Ihre Kommentarlösung besser als diese. Warte ... du hast es entfernt? –

+1

@BondedDust, nein. Ich habe es Richard gegeben, seit er an Max.col dachte. Oh, und vielen Dank für Ihren anderen Kommentar heute :-) – A5C1D2H2I1M1N2O1R2T1

3

um das Ergebnis von Ihrem apply() Anruf in einen Datenrahmen zu setzen, könnten Sie

df <- data.frame(id=data$id, 
      largest_value_var=apply(data[,-1], 1, function(x) names(x)[which.max(x)])) 

Hinweis tun, dass c(names(x)) die gleichen wie names(x) sind, so dass ich weggelassen c().

+0

@RichardScriven, es ist eigentlich keine Gruppierung in diesem Fall erforderlich. – A5C1D2H2I1M1N2O1R2T1

Verwandte Themen