2016-08-30 2 views
1

ich einen Datenrahmen haben, sagenPicking up nur bestimmte Spalten basierend auf Bedingungen auf mehrere Spalten in R

df <- data.frame(x = c(1,2,5,6,3,3,3,6,8,8,8,8), 
      y = c(1,1,1,1,1,2,3,1,1,2,3,4), 
      z = c("a","b","c","d","e","f","g","h","i","j","k","l")) 

es wie dieses Ich einzigartige Elemente aus der Spalte x holen möchte

x y z 
1 1 1 a 
2 2 1 b 
3 5 1 c 
4 6 1 d 
5 3 1 e 
6 3 2 f 
7 3 3 g 
8 6 1 h 
9 8 1 i 
10 8 2 j 
11 8 3 k 
12 8 4 l 

sieht basierend auf der Spalte y, so dass y maximal sein sollte (in diesem Fall sagen wir für Zeile Nummer 5 bis 7 sind 3'3), würde ich gerne das x = 3 entsprechend y = 3 (maximaler Wert) ähnlich für x = 8 auswählen Ich möchte wählen y = 4 row)

die Ausgabe wie dies

x y z 
1 1 1 a 
2 2 1 b 
3 5 1 c 
4 6 1 d 
5 3 3 g 
6 6 1 h 
7 8 4 l 

aussehen soll ich eine Lösung für die, die ich in der Lösung bin Entsendung, aber wenn es sich eine bessere Methode, dies zu erreichen, arbeitet Meine Lösung nur in diesem speziellen Fall (die größte Auswahl) Was ist die allgemeine Falllösung dafür?

Antwort

2

Eine Lösung dplyr

library(dplyr) 
df %>% 
group_by(x) %>% 
slice(max(y)) 

#  x  y  z 
# (dbl) (dbl) (chr) 
#1  1  1  a 
#2  2  1  b 
#3  3  3  g 
#4  5  1  c 
#5  6  1  d 
#6  8  4  l 

Die base R Alternative verwendet wird aggregate

mit
aggregate(y~x, df, max) 
+0

hinzu Ich würde es wahrscheinlich auch "arrangieren", wenn Sie die Beobachtungen umkehren, wird das Ergebnis abweichen. –

0

Hier ist meine Lösung mit dplyr Paket

library(dplyr) 
df <- data.frame(x = c(1,2,5,6,3,3,3,6,8,8,8,8), 
       y = c(1,1,1,1,1,2,3,1,1,2,3,4), 
       z = c("a","b","c","d","e","f","g","h","i","j","k","l")) 
df <- arrange(df,desc(y)) 
df_out <- df[!duplicated(df$x),] 
df_out 

Printing df_out

x y z 
1 8 4 l 
2 3 3 g 
6 1 1 a 
7 2 1 b 
8 5 1 c 
9 6 1 d 
+1

'arrange' und' desc' sind nicht R Basisfunktionen, sollten Sie das Paket, das sie gehören erwähnen. –

+0

@Rohak, korrigiert die Ausgabe; und Jilber, fügte Paketinfo – Kou

2

Sie können das gleiche Ergebnis mit einer dplyr Kette und dplyrgroup_by Funktion erreichen. Sobald Sie eine group_by Funktion verwenden, werden die restlichen Funktionen in der Kette innerhalb der Gruppe im Gegensatz zur gesamten data.frame angewendet. Also hier filter wo die einzigen übrig gebliebenen Zeilen die max(y) pro Gruppierungswert von x sind. Dies kann erweitert werden, um für die min von y oder einen bestimmten Wert verwendet werden.

Ich denke, es ist in der Regel gute Praxis zu ungroup die Daten am Ende einer Kette mit group_by, um jedes unerwartete Verhalten zu vermeiden.

library(dplyr) 
df <- data.frame(x = c(1,2,5,6,3,3,3,6,8,8,8,8), 
      y = c(1,1,1,1,1,2,3,1,1,2,3,4), 
      z = c("a","b","c","d","e","f","g","h","i","j","k","l")) 
df %>% 
    group_by(x) %>% 
    filter(y==max(y)) %>% 
    ungroup() 

Um es allgemeiner zu machen ... sagen Sie stattdessen die mean von y für ein gegebenes x zum max im Gegensatz wollten. Sie könnten dann die summarise Funktion anstelle der filter wie unten gezeigt verwenden.

df %>% 
    group_by(x) %>% 
    summarise(y=mean(y)) %>% 
    ungroup() 
+0

Danke, habe nicht daran gedacht. – Kou

0

den Datenrahmen von df[order(df$x, df$y),] bestellt Unter der Annahme, wie es in dem Beispiel ist, können Sie Basis R-Funktionen, split, lapply und do.call/rbind zu extrahieren Ihre gewünschten Zeilen mit der „Split/apply/kombinieren“ Methodik verwenden .

do.call(rbind, lapply(split(df, df$x), function(i) i[nrow(i),])) 
    x y z 
1 1 1 a 
2 2 1 b 
3 3 3 g 
5 5 1 c 
6 6 1 h 
8 8 4 l 

split aufbricht der data.frame in eine Liste auf x basiert. Diese Liste wird an lapply übergeben, die die letzte Zeile jedes data.frames auswählt und diese Daten der einen Zeile zurückgibt.Frames als Liste. Diese Liste wird dann rbind in einen einzelnen Datenrahmen unter Verwendung do.call editiert.

1

data.table Verwendung können wir df[order(z), .I[which.max(y)], by = x] verwenden, um die rownumbers von Interesse zu erhalten, zum Beispiel:

library(data.table) 
setDT(df) 
df[df[order(z), .I[which.max(y)], by = x][, V1]] 

    x y z 
1: 1 1 a 
2: 2 1 b 
3: 5 1 c 
4: 6 1 d 
5: 3 3 g 
6: 8 4 l 
Verwandte Themen