wake-up-neo.com

Entfernen Sie doppelte Zeilen mit dplyr

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.

100
Nishanth

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)
113
hadley

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)
164
davechilders

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.

24
Konrad Rudolph

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));
2
Anton Andreev

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()
0
davsjob

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)

Unterschied zur Verwendung der Funktion 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)
0
bschneidr