"छोटे सब्सक्रिप्शन वाले तत्व" सहित सभी डुप्लिकेट पंक्तियाँ ढूँढना


111

R duplicatedएक सदिश को दिखाता है कि क्या वेक्टर या डेटा फ़्रेम का प्रत्येक तत्व एक छोटे सबस्क्रिप्ट के साथ एक तत्व का डुप्लिकेट है। इसलिए यदि 5-पंक्ति डेटा फ़्रेम की पंक्तियाँ 3, 4 और 5 समान हैं, duplicatedतो मुझे वेक्टर देगा

FALSE, FALSE, FALSE, TRUE, TRUE

लेकिन इस मामले में मैं वास्तव में प्राप्त करना चाहता हूं

FALSE, FALSE, TRUE, TRUE, TRUE

यह है, मैं जानना चाहता हूं कि क्या एक पंक्ति को एक बड़ी सबस्क्रिप्ट के साथ पंक्ति द्वारा दोहराया गया है या नहीं।

जवाबों:


128

duplicatedएक fromLastतर्क है। "उदाहरण" अनुभाग ?duplicatedआपको दिखाता है कि इसका उपयोग कैसे करना है। बस duplicatedदो बार कॉल करें , एक बार साथ fromLast=FALSEऔर एक बार साथ fromLast=TRUEमें पंक्तियों को ले जाएँ TRUE


कुछ देर से संपादित करें: आपने एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण प्रदान नहीं किया है, इसलिए यहाँ एक उदाहरण @jbaums द्वारा योगदान दिया गया है

vec <- c("a", "b", "c","c","c") 
vec[duplicated(vec) | duplicated(vec, fromLast=TRUE)]
## [1] "c" "c" "c"

संपादित करें: और डेटा फ्रेम के मामले के लिए एक उदाहरण:

df <- data.frame(rbind(c("a","a"),c("b","b"),c("c","c"),c("c","c")))
df[duplicated(df) | duplicated(df, fromLast=TRUE), ]
##   X1 X2
## 3  c  c
## 4  c  c

3
रुको, मैंने अभी एक परीक्षण किया और पाया कि मैं गलत था: x <- c(1:9, 7:10, 5:22); y <- c(letters, letters[1:5]); test <- data.frame(x, y); test[duplicated(test$x) | duplicated(test$x, fromLast=TRUE), ]उसने तीनों को 7, ran , और ९ की प्रतियों में लौटा दिया। वह काम क्यों करता है?
जोएम ०५

1
क्योंकि यदि आप अंत से या सामने से शुरू करते हैं, तो बीच वाले को कोई फर्क नहीं पड़ता। उदाहरण के लिए, duplicated(c(1,1,1))बनाम duplicated(c(1,1,1,), fromLast = TRUE)देता है c(FALSE,TRUE,TRUE)और c(TRUE,TRUE,FALSE)। मध्य मूल्य TRUEदोनों मामलों में है। ले रहा है |दोनों वैक्टर की देता है c(TRUE,TRUE,TRUE)
ब्रैंडन

34

आपको duplicatedमूल्यों के सेट को इकट्ठा करने , लागू करने uniqueऔर फिर परीक्षण करने की आवश्यकता है %in%। हमेशा की तरह, एक नमूना समस्या इस प्रक्रिया को जीवंत बना देगी।

> vec <- c("a", "b", "c","c","c")
> vec[ duplicated(vec)]
[1] "c" "c"
> unique(vec[ duplicated(vec)])
[1] "c"
>  vec %in% unique(vec[ duplicated(vec)]) 
[1] FALSE FALSE  TRUE  TRUE  TRUE

इस बात से सहमत। प्रसंस्करण धीमा भी कर सकते हैं, लेकिन इसे बहुत धीमा करने की संभावना नहीं है।
IRTFM

काफी सच। ओपी ने डेटाफ्रेम में "कभी डुप्लिकेट" पंक्तियों के लिए परीक्षण करने के लिए एक डेटा उदाहरण नहीं दिया। मुझे लगता है कि उपयोग करने के मेरे सुझाव duplicated, uniqueऔर %in%आसानी से एक डेटाफ्रेम के लिए सामान्यीकृत किया जा सकता है अगर कोई pasteएक असामान्य विभाजक चरित्र के साथ पहली पंक्ति में हो। (स्वीकृत उत्तर बेहतर है।)
IRTFM

3

मेरे पास एक ही सवाल है , और अगर मुझसे गलती नहीं है, तो यह भी एक जवाब है।

vec[col %in% vec[duplicated(vec$col),]$col]

डननो जो एक तेज़ है, हालांकि, वर्तमान में मैं जिस डेटासेट का उपयोग कर रहा हूं, वह परीक्षण करने के लिए पर्याप्त नहीं है जो महत्वपूर्ण समय अंतराल का उत्पादन करता है।


1
यह उत्तर vecपरमाणु वेक्टर के रूप में और डेटाफ्रेम के रूप में दोनों का उपयोग करता है। मुझे संदेह है कि वास्तविक डेटफ़्रेम के साथ यह विफल हो जाएगा।
IRTFM

3

एक dataframe में डुप्लिकेट पंक्तियों के साथ प्राप्त किया जा सकता dplyrकरने से

df = bind_rows(iris, head(iris, 20)) # build some test data
df %>% group_by_all() %>% filter(n()>1) %>% ungroup()

group_by_at(vars(-var1, -var2))डेटा को समूहीकृत करने के बजाय कुछ स्तंभों का उपयोग किया जा सकता है।

यदि पंक्ति सूचक और न केवल डेटा वास्तव में आवश्यक है, तो आप उन्हें पहले जोड़ सकते हैं:

df %>% add_rownames %>% group_by_at(vars(-rowname)) %>% filter(n()>1) %>% pull(rowname)

1
का अच्छा उपयोग n()। परिणामी डेटाफ़्रेम को अनग्रुप करना न भूलें।
क्यूर

@qwr मैंने परिणाम को अनपग्र करने के लिए उत्तर समायोजित कर दिया है
Holger Brandl

2

यहाँ एक समारोह के रूप में @ जोशुआ उलरिच का समाधान है। यह प्रारूप आपको उसी कोड का उपयोग करने की अनुमति देता है जिस शैली में आप डुप्लिकेट () का उपयोग करेंगे:

allDuplicated <- function(vec){
  front <- duplicated(vec)
  back <- duplicated(vec, fromLast = TRUE)
  all_dup <- front + back > 0
  return(all_dup)
}

उसी उदाहरण का उपयोग करना:

vec <- c("a", "b", "c","c","c") 
allDuplicated(vec) 
[1] FALSE FALSE  TRUE  TRUE  TRUE

0

यदि आप रुचि रखते हैं जिसमें पंक्तियों को कुछ स्तंभों के लिए डुप्लिकेट किया गया है, तो आप प्लाई दृष्टिकोण का उपयोग कर सकते हैं :

ddply(df, .(col1, col2), function(df) if(nrow(df) > 1) df else c())

Dplyr के साथ एक गणना चर जोड़ना :

df %>% add_count(col1, col2) %>% filter(n > 1)  # data frame
df %>% add_count(col1, col2) %>% select(n) > 1  # logical vector

डुप्लिकेट पंक्तियों के लिए (सभी कॉलमों पर विचार):

df %>% group_by_all %>% add_tally %>% ungroup %>% filter(n > 1)
df %>% group_by_all %>% add_tally %>% ungroup %>% select(n) > 1

इन दृष्टिकोणों का लाभ यह है कि आप निर्दिष्ट कर सकते हैं कि कटऑफ के रूप में कितने डुप्लिकेट हैं।


0

मुझे एक समान समस्या थी लेकिन मुझे विशिष्ट कॉलम में मूल्यों द्वारा डुप्लिकेट पंक्तियों की पहचान करने की आवश्यकता थी। मैं निम्नलिखित dplyr समाधान के साथ आया :

df <- df %>% 
  group_by(Column1, Column2, Column3) %>% 
  mutate(Duplicated = case_when(length(Column1)>1 ~ "Yes",
                            TRUE ~ "No")) %>%
  ungroup()

कोड विशिष्ट कॉलम द्वारा पंक्तियों को समूहित करता है। यदि किसी समूह की लंबाई 1 से अधिक है तो समूह में सभी पंक्तियों को दोहराया गया है। एक बार यह हो जाने पर आप Duplicatedफ़िल्टरिंग आदि के लिए कॉलम का उपयोग कर सकते हैं ।

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