Ich habe einen Datenrahmen wie diesen -
set.seed(123)
df = data.frame(x=sample(0:1,10,replace=T),y=sample(0:1,10,replace=T),z=1:10)
> df
x y z
1 0 1 1
2 1 0 2
3 0 1 3
4 1 1 4
5 1 0 5
6 0 1 6
7 1 0 7
8 1 0 8
9 1 0 9
10 0 1 10
Ich möchte doppelte Zeilen basierend auf den ersten beiden Spalten entfernen. Erwartete Ausgabe -
df[!duplicated(df[,1:2]),]
x y z
1 0 1 1
2 1 0 2
4 1 1 4
Ich suche speziell nach einer Lösung mit dplyr
-Paket.
Hinweis : dplyr
enthält jetzt die distinct
-Funktion für diesen Zweck.
Ursprüngliche Antwort unten:
library(dplyr)
set.seed(123)
df <- data.frame(
x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
)
Ein Ansatz wäre, zu gruppieren und dann nur die erste Reihe beizubehalten:
df %>% group_by(x, y) %>% filter(row_number(z) == 1)
## Source: local data frame [3 x 3]
## Groups: x, y
##
## x y z
## 1 0 1 1
## 2 1 0 2
## 3 1 1 4
(In Dplyr 0.2 benötigen Sie nicht die Dummyvariable z
und können nur row_number() == 1
schreiben.)
Ich habe auch darüber nachgedacht, eine slice()
-Funktion hinzuzufügen, die folgendermaßen funktionieren würde:
df %>% group_by(x, y) %>% slice(from = 1, to = 1)
Oder vielleicht eine Variation von unique()
, mit der Sie auswählen können, welche -Variablen verwendet werden sollen:
df %>% unique(x, y)
Hier ist eine Lösung mit dplyr 0.3
.
library(dplyr)
set.seed(123)
df <- data.frame(
x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
)
> df %>% distinct(x, y)
x y z
1 0 1 1
2 1 0 2
3 1 1 4
Aktualisiert für Dplyr 0.5
das Standardverhalten von dplyr Version 0.5 von distinct()
gibt nur die im Argument ...
angegebenen Spalten zurück.
Um das ursprüngliche Ergebnis zu erzielen, müssen Sie jetzt Folgendes verwenden:
df %>% distinct(x, y, .keep_all = TRUE)
Der Vollständigkeit halber funktioniert auch Folgendes:
df %>% group_by(x) %>% filter (! duplicated(y))
Ich bevorzuge jedoch die Lösung mit distinct
und vermute, dass sie auch schneller ist.
Bei der Auswahl von Spalten in R für einen reduzierten Datensatz können Sie oft Duplikate erhalten.
Diese beiden Zeilen ergeben das gleiche Ergebnis. Jeder gibt einen eindeutigen Datensatz mit nur zwei ausgewählten Spalten aus:
distinct(mtcars, cyl, hp);
summarise(group_by(mtcars, cyl, hp));
Wenn Sie die duplizierten Zeilen suchen möchten, können Sie find_duplicates
aus hablar
verwenden:
library(dplyr)
library(hablar)
df <- tibble(a = c(1, 2, 2, 4),
b = c(5, 2, 2, 8))
df %>% find_duplicates()
Die beste Lösung ist distinct()
von dplyr, wie bereits angedeutet.
Hier ist jedoch ein anderer Ansatz, der die Funktion slice()
von dplyr verwendet.
# Generate fake data for the example
library(dplyr)
set.seed(123)
df <- data.frame(
x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
)
# In each group of rows formed by combinations of x and y
# retain only the first row
df %>%
group_by(x, y) %>%
slice(1)
distinct()
Der Vorteil dieser Lösung besteht darin, dass explizit angegeben wird, welche Zeilen vom ursprünglichen Datenrahmen beibehalten werden, und dass sie sich gut mit der Funktion arrange()
paaren kann.
Angenommen, Sie hatten Kundenvertriebsdaten und wollten pro Kunde einen Datensatz aufbewahren, und Sie möchten, dass dieser Datensatz der letzte Einkauf ist. Dann könntest du schreiben:
customer_purchase_data %>%
arrange(desc(Purchase_Date)) %>%
group_by(Customer_ID) %>%
slice(1)