डुप्लिकेट का उपयोग करके डुप्लिकेट पंक्तियाँ निकालें


128

मेरे पास एक data.frame है जैसे -

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

मैं पहले दो कॉलम के आधार पर डुप्लिकेट पंक्तियों को निकालना चाहता हूं। अपेक्षित उत्पादन -

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

मैं विशेष रूप से dplyrपैकेज का उपयोग कर एक समाधान की तलाश में हूं ।

जवाबों:


137

नोट : dplyrअब distinctइस उद्देश्य के लिए फ़ंक्शन शामिल है ।

नीचे मूल उत्तर:


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 %>% 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

(Duspr 0.2 में आपको डमी zवैरिएबल की आवश्यकता नहीं होगी और बस लिखने में सक्षम होंगे row_number() == 1)

मैं एक slice()फ़ंक्शन जोड़ने के बारे में भी सोच रहा हूं जो काम करेगा:

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

या हो सकता है unique()कि इसका एक भिन्न रूप आपको यह चुनने दे कि कौन से चर का उपयोग करना है:

df %>% unique(x, y)

4
@dotcomken तब तक भी इस्तेमाल कर सकता थाdf %>% group_by(x, y) %>% do(head(.,1))
Holger Brandl

16
@MahbubulMajumder जो काम करेगा, लेकिन काफी धीमा है। dplyr 0.3 होगाdistinct()
हैडली

3
@hadley I को अनोखा () और विशिष्ट () फ़ंक्शन पसंद है, हालांकि, वे सभी डेटा फ्रेम से 2 डुप्लिकेट को हटा देते हैं। क्या होगा यदि मैं डुप्लिकेट मान के सभी 1 मुठभेड़ों को निकालना चाहता हूं? यह कैसे किया जा सकता है? किसी भी मदद के लिए धन्यवाद!
फ्लाइंगडच

2
@MvZB - क्या आप अभी (desc ()) की व्यवस्था नहीं करेंगे और फिर अलग उपयोग करेंगे?
वुडस्टॉक

मुझे यकीन है कि एक सरल समाधान है लेकिन क्या होगा अगर मैं दोनों डुप्लिकेट पंक्तियों से छुटकारा चाहता हूं? मैं अक्सर जैविक नमूनों से जुड़े मेटाडेटा के साथ काम करता हूं और अगर मेरे पास डुप्लिकेट नमूना आईडी हैं, तो मैं अक्सर यह सुनिश्चित नहीं कर सकता कि किस पंक्ति में सही डेटा है। सबसे गलत शर्त गलत मेटाडेटा संघों से बचने के लिए दोनों को डंप करना है। डुप्लिकेट सैंपल आईडी की सूची बनाने और उन आईडी से पंक्तियों को फ़िल्टर करने के अलावा कोई आसान उपाय?
glongo_fishes

191

यहाँ एक समाधान का उपयोग कर रहा है 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
यह समाधान हैडली द्वारा प्रदान किए गए की तुलना में बहुत तेजी से (मेरे मामले में 10 गुना) प्रतीत होता है।
कैलिमो

101
तकनीकी रूप से यह भी हेडली :-)
टायलर रिंकर

27

पूर्णता के लिए, निम्नलिखित भी काम करता है:

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

हालांकि, मैं समाधान का उपयोग करना पसंद करता हूं distinct, और मुझे संदेह है कि यह तेज है, भी।


7

अधिकांश समय, सबसे अच्छा समाधान distinct()dplyr से उपयोग कर रहा है, जैसा कि पहले ही सुझाव दिया गया है।

हालांकि, यहां एक और दृष्टिकोण है जो slice()dplyr से फ़ंक्शन का उपयोग करता है ।

# 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()फ़ंक्शन का उपयोग करने से अंतर

इस समाधान का लाभ यह है कि यह स्पष्ट करता है कि कौन सी पंक्तियों को मूल डेटाफ़्रेम से बनाए रखा गया है, और यह arrange()फ़ंक्शन के साथ अच्छी तरह से जोड़ सकता है।

मान लें कि आपके पास ग्राहक बिक्री डेटा था और आप प्रति ग्राहक एक रिकॉर्ड बनाए रखना चाहते थे, और आप चाहते हैं कि रिकॉर्ड उनकी नवीनतम खरीद से हो। तब आप लिख सकते हैं:

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

3

कम डेटा-सेट के लिए आर में कॉलम का चयन करते समय आप अक्सर डुप्लिकेट के साथ समाप्त हो सकते हैं।

ये दोनों रेखाएं समान परिणाम देती हैं। प्रत्येक चयनित दो स्तंभों के साथ एक अद्वितीय डेटा-सेट आउटपुट करता है:

distinct(mtcars, cyl, hp);

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

1

यदि आप पंक्तियों दोहराया गया है कि आप उपयोग कर सकते हैं पता लगाना चाहते हैं find_duplicatesसे hablar:

library(dplyr)
library(hablar)

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

df %>% find_duplicates()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.