2017-04-14 1 views
1

Ich habe eine große Tabelle mit Tausenden von Einträgen aus einer Datenbank mit einer Struktur ähnlich der in Tabelle 1 in der Abbildung unten abgefragt. Ich möchte die doppelte Zeile behalten, die den höchsten Wert für Var 1 hat, wie in Tabelle 2 gezeigt. Die Situation ist ähnlich der, die in einer früheren Abfrage in diesem Forum remove duplicates based on one column and keep last entry beschrieben wird. Die Auswahl der Zeilen mit einer einfachen for-Schleife funktioniert, es dauert jedoch sehr lange. Gibt es eine schnellere elegante Art, dies in R zu handhaben?Behalten Sie den letzten Eintrag, aber entfernen Sie andere doppelte Zeile (n) in einem Datenrahmen mit R

Table1 <- structure(list(Var1 = 1001:1009, Var2 = c("AAA", "BBB", "CCC", 
"AAA", "DDD", "BBB", "AAA", "EEE", "DDD"), Var3 = c(95L, 100L, 
90L, 95L, 85L, 100L, 95L, 45L, 85L), Var4 = c("mg", "kg", "pg", 
"mg", "mg", "kg", "mg", "mg", "mg")), .Names = c("Var1", "Var2", 
"Var3", "Var4"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-9L), spec = structure(list(cols = structure(list(Var1 = structure(list(), class = c("collector_integer", 
"collector")), Var2 = structure(list(), class = c("collector_character", 
"collector")), Var3 = structure(list(), class = c("collector_integer", 
"collector")), Var4 = structure(list(), class = c("collector_character", 
"collector"))), .Names = c("Var1", "Var2", "Var3", "Var4")), 
    default = structure(list(), class = c("collector_guess", 
    "collector"))), .Names = c("cols", "default"), class = "col_spec")) 

enter image description here

Antwort

1

Wir slice nach dem Gruppieren von

library(dplyr) 
Table1 %>% 
    group_by(Var2) %>% 
    slice(which.max(Var1)) %>% 
    arrange(Var1) 
#  Var1 Var2 Var3 Var4  
#  <int> <chr> <int> <chr> 
# 1 1003 CCC 90 pg 
# 2 1006 BBB 100 kg 
# 3 1007 AAA 95 mg 
# 4 1008 EEE 45 mg 
# 5 1009 DDD 85 mg 

'Var2' verwenden können Oder eine arrange und dann filter die nicht dupliziert

Table1 %>% 
    arrange(Var2, -Var1) %>% 
    filter(!duplicated(Var2)) %>% 
    arrange(Var1) 

Oder mit data.table

library(data.table) 
setDT(Table1)[order(Var2,-Var1)][!duplicated(Var2)][order(Var1)] 

HINWEIS: Dies kann mit fromLast=TRUE mit duplicated innerhalb eines Schrittes erfolgen, aber hier sind wir, ob die Werte nicht sicher sind bereits in den ursprünglichen Daten-Set bestellt oder nicht. So kompakt Verfahren bedeutet nicht, dass es immer

arbeitet Wir verwenden auch einen kompakten Code

Table1[c(3, 6:9),] 

als eine andere Art und Weise :-) die erwartete zu bekommen

1

In Basis R können wir Verwenden Sie ave, um eine Gruppenoperation durchzuführen. Hier wird ein logischer Vektor zurückgegeben, der anzeigt, ob die Beobachtung gleich dem maximalen Wert von Var1 ist. Dies wird zur Untermenge verwendet.

Table1[as.logical(ave(Table1$Var1, Table1$Var2, FUN=function(i) i == max(i))),] 
    Var1 Var2 Var3 Var4 
3 1003 CCC 90 pg 
6 1006 BBB 100 kg 
7 1007 AAA 95 mg 
8 1008 EEE 45 mg 
9 1009 DDD 85 mg 
+0

Ihre Antwort gab mir Ideen zur Lösung dieses und anderer Probleme, die ich beheben möchte. – RanonKahn

3

duplicated haben eine fromLast Option!

Table1[!duplicated(Table1$Var2, fromLast = T), ] 

Es sollte beachtet werden, dass wir durch Var1 zuerst, wenn die Daten zu sortieren haben, werden nicht bereits von Var1 bestellt.

+0

@MikeH. Sicher. Du kommst kommen, wenn ich darüber schreibe. – mt1022

+0

Sehr eleganter Ansatz. – RanonKahn

Verwandte Themen