Dplyr kullanarak yinelenen satırları kaldırın


128

Bunun gibi bir data.frame var -

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

İlk iki sütuna göre yinelenen satırları kaldırmak istiyorum. Beklenen çıktı -

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

Özellikle dplyrpaket kullanarak bir çözüm arıyorum .

Yanıtlar:


137

Not : dplyrartıkdistinct bu amaç işlevi .

Aşağıdaki orijinal cevap:


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
)

Bir yaklaşım, gruplamak ve ardından yalnızca ilk satırı tutmak olabilir:

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

(Dplyr 0.2'de kukla zdeğişkene ihtiyacınız olmayacak ve sadece yazabileceksiniz row_number() == 1)

Ayrıca slice()şöyle çalışacak bir işlev eklemeyi düşünüyordum :

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

Veya bunun bir varyasyonu, unique()hangi değişkenleri kullanacağınızı seçmenize izin verir:

df %>% unique(x, y)

4
@dotcomken O zamana kadar sadece şunu da kullanabilirdidf %>% group_by(x, y) %>% do(head(.,1))
Holger Brandl

16
@MahbubulMajumder çalışacak, ancak oldukça yavaş. dplyr 0.3 sahip olacakdistinct()
hadley

3
@hadley Benzersiz () ve farklı () işlevini seviyorum, ancak hepsi veri çerçevesinden 2. kopyayı kaldırıyor. yinelenen değerin tüm 1. karşılaşmalarının kaldırılmasını istersem ne olur? Bu nasıl yapılabilir? Herhangi bir yardım için teşekkürler!
FlyingDutch

2
@MvZB - (desc ()) düzenleyip sonra farklı kullanmaz mısın?
Woodstock

Eminim basit bir çözüm vardır, ancak ya iki yinelenen satırdan kurtulmak istersem? Genellikle biyolojik örneklerle ilişkili meta verilerle çalışırım ve yinelenen örnek kimliklerim varsa, hangi satırın doğru verilere sahip olduğundan genellikle emin olamıyorum. En güvenli bahis, hatalı meta veri ilişkilendirmelerini önlemek için her ikisini de atmaktır. Yinelenen numune kimliklerinin bir listesini yapmak ve bu kimliklerle satırları filtrelemekten başka kolay bir çözüm var mı?
glongo_fishes

191

İşte kullanarak bir çözüm dplyr >= 0.5.

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, .keep_all = TRUE)
    x y z
  1 0 1 1
  2 1 0 2
  3 1 1 4

3
Bu çözüm, Hadley tarafından sağlanan çözümden çok daha hızlı (benim durumumda 10 kat) görünmektedir.
Calimo

101
Teknik olarak bu da Hadley tarafından sağlanan bir çözüm :-)
Tyler Rinker

27

Bütünlük adına, aşağıdakiler de işe yarar:

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

Ancak çözümü kullanmayı tercih ediyorum distinctve bunun da daha hızlı olduğundan şüpheleniyorum.


7

Daha distinct()önce önerildiği gibi çoğu zaman en iyi çözüm dplyr'den kullanmaktır .

Ancak, slice()dplyr'deki işlevi kullanan başka bir yaklaşım burada .

# 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)

Kullanmanın farkı distinct()İşlevi

Bu çözümün avantajı, hangi satırların orijinal veri çerçevesinden saklandığını açıkça belirtmesi ve işlevle güzel bir şekilde eşleşebilmesidir arrange().

Diyelim ki müşteri satış verileriniz var ve her müşteri için bir kayıt tutmak istiyorsunuz ve bu kaydın en son satın almalarındaki kayıt olmasını istiyorsunuz. O zaman yazabilirsin:

customer_purchase_data %>%
   arrange(desc(Purchase_Date)) %>%
   group_by(Customer_ID) %>%
   slice(1)

3

Küçültülmüş bir veri kümesi için R'de sütunları seçerken, çoğu zaman kopyalar elde edebilirsiniz.

Bu iki çizgi aynı sonucu verir. Her biri, yalnızca seçilen iki sütuna sahip benzersiz bir veri kümesi üretir:

distinct(mtcars, cyl, hp);

summarise(group_by(mtcars, cyl, hp));

1

Çoğaltılmış satırları bulmak istiyorsanız find_duplicatesşuradan kullanabilirsiniz hablar:

library(dplyr)
library(hablar)

df <- tibble(a = c(1, 2, 2, 4),
             b = c(5, 2, 2, 8))

df %>% find_duplicates()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.