Usuń zduplikowane wiersze za pomocą dplyr

Mam dane.frame like this -

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

Chciałbym usunąć zduplikowane wiersze oparte na dwóch pierwszych kolumnach. Oczekiwana wydajność -

df[!duplicated(df[,1:2]),]
  x y z
1 0 1 1
2 1 0 2
4 1 1 4

Szukam rozwiązania przy użyciu dplyr pakietu.

 94
Author: Nishanth, 2014-04-09

4 answers

Uwaga: dplyr Teraz zawiera distinct funkcję do tego celu.

Oryginalna odpowiedź poniżej:


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
)

Jednym podejściem byłoby grupowanie, a następnie zachowywanie tylko pierwszego rzędu:

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

(W dplyr 0.2 nie będzie potrzebna zmienna z i będzie możliwość zapisu row_number() == 1)

Myślałem też o dodaniu slice() funkcji, która praca jak:

df %>% group_by(x, y) %>% slice(from = 1, to = 1)

A może odmiana unique(), która pozwoli Ci wybrać które zmienne do użycia:

df %>% unique(x, y)
 105
Author: hadley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 12:57:13

Oto rozwiązanie za pomocą 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

Aktualizacja dla dplyr 0.5

Dplyr w wersji 0.5 domyślne zachowanie distinct() zwraca tylko kolumny określone w argumencie ....

Aby osiągnąć oryginalny wynik, musisz teraz użyć:

df %>% distinct(x, y, .keep_all = TRUE)
 152
Author: davechilders,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 14:02:41

Ze względu na kompletność, działa również:

df %>% group_by(x) %>% filter (! duplicated(y))

Jednak wolę rozwiązanie używając distinct i podejrzewam, że jest też szybsze.

 19
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-04 11:19:45

Podczas wybierania kolumn w R dla zredukowanego zbioru danych często można skończyć duplikatami.

Te dwie linie dają ten sam wynik. Każdy wyprowadza unikalny zestaw danych tylko z dwoma wybranymi kolumnami:

distinct(mtcars, cyl, hp);

summarise(group_by(mtcars, cyl, hp));
 1
Author: Anton Andreev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-16 11:13:20