r में डुप्लिकेट पंक्तियों को पहचानें और चिह्नित करें


11

मैं 2 कॉलमों के आधार पर डुप्लिकेट पंक्तियों को पहचानना और चिन्हित करना चाहूंगा। मैं प्रत्येक डुप्लिकेट के लिए एक विशिष्ट पहचानकर्ता बनाना चाहूंगा ताकि मुझे पता न चले कि पंक्ति एक डुप्लिकेट है, लेकिन यह किस पंक्ति के साथ डुप्लिकेट है। मेरे पास एक डेटाफ्रेम है जो नीचे कुछ डुप्लिकेट आइटम जोड़े (फिट और बैठें) और अन्य जोड़े के साथ दिखता है जो डुप्लिकेट नहीं हैं। जबकि आइटम जोड़े डुप्लिकेट हैं, उनके पास मौजूद जानकारी अद्वितीय है (उदाहरण के लिए, 1 पंक्ति में मान 1 में एक मान होगा, लेकिन मान 2 और मान 3 नहीं, दूसरी या 'डुप्लिकेट' पंक्ति में मान 2 और मान 3 के लिए संख्याएँ होंगी नहीं 1)

वर्तमान डेटाफ़्रेम

     value1 value2 value3 fit   sit  
[1,] "1"    NA     NA     "it1" "it2"
[2,] NA     "3"    "2"    "it2" "it1"
[3,] "2"    "3"    "4"    "it3" "it4"
[4,] NA     NA     NA     "it4" "it3"
[5,] "5"    NA     NA     "it5" "it6"
[6,] NA     NA     "2"    "it6" "it5"
[7,] NA     "4"    NA     "it7" "it9"

कोड उदाहरण डेटाफ्रेम उत्पन्न करने के लिए

value1<-c(1,NA,2,NA,5,NA,NA)
value2<-c(NA,3,3,NA,NA,NA, 4)
value3<-c(NA,2,4,NA,NA,2, NA)
fit<-c("it1","it2","it3","it4", "it5", "it6","it7")
sit<-c("it2","it1","it4","it3", "it6", "it5", "it9")
df.now<-cbind(value1,value2,value3, fit, sit)

मैं जो चाहता हूं, उसे इस तरह दिखने वाली डेटाफ़्रेम में बदलना है:

वांछित डेटाफ़्रेम

     val1 val2 val3 it1   it2  
[1,] "1"  "3"  "2"  "it1" "it2"
[2,] "2"  "3"  "4"  "it3" "it4"
[3,] "5"  NA   "2"  "it5" "it6"
[4,] NA   "4"  NA   "it7" "it9"

मैं निम्नलिखित चरणों को करने के बारे में सोच रहा था: 1. डुप्लिकेट जोड़े की पहचान करने के लिए सबसे कम आइटम और उच्चतम वस्तुओं के साथ बैठकर नए वेरिएबल्स बनाएं और डुप्लिकेट आइटम जोड़े की पहचान करें 3. अनूठे जानकारी का चयन करने और भरने के लिए ifelse का उपयोग करें।

मुझे पता है कि चरण 1 और 3 कैसे करना है, लेकिन मैं चरण 2 में फंस गया हूं। मुझे लगता है कि मुझे जो करने की आवश्यकता है वह सिर्फ TRUE / FALSE डुप्लिकेट की पहचान नहीं है, लेकिन शायद इस तरह प्रत्येक आइटम जोड़ी के लिए एक अद्वितीय पहचानकर्ता के साथ एक कॉलम है (वहां मेरे चरण 1 के कारण 2 अतिरिक्त पंक्तियाँ हैं):

     value1 value2 value3 fit   sit   lit   hit    dup
[1,] "1"    NA     NA     "it1" "it2" "it1" "it2"   1
[2,] NA     "3"    "2"    "it2" "it1" "it1" "it2"   1
[3,] "2"    "3"    "4"    "it3" "it4" "it3" "it4"   2
[4,] NA     NA     NA     "it4" "it3" "it3" "it4"   2
[5,] "5"    NA     NA     "it5" "it6" "it5" "it6"   3
[6,] NA     NA     "2"    "it6" "it5" "it5" "it6"   3
[7,] NA     "4"    NA     "it7" "it9" "it7" "it9"   NA

मुझे यकीन नहीं है कि यह कैसे करना है।

जो मैं पूछ रहा हूं वह या तो चरण 2 के साथ मदद करता है या शायद मेरे द्वारा बताए गए चरणों की तुलना में इसे हल करने का एक बेहतर तरीका है।

जवाबों:


6

एक dplyrविकल्प हो सकता है:

df.now %>%
 group_by(pair = paste(pmax(fit, sit), pmin(fit, sit), sep = "_")) %>%
 summarise_at(vars(starts_with("value")), ~ ifelse(all(is.na(.)), 
                                                   NA,
                                                   first(na.omit(.))))

  pair    value1 value2 value3
  <chr>    <dbl>  <dbl>  <dbl>
1 it2_it1      1      3      2
2 it4_it3      2      3      4
3 it6_it5      5     NA      2
4 it9_it7     NA      4     NA

और अगर आपको व्यक्तिगत कॉलम में जोड़े की आवश्यकता है, तो इसके अतिरिक्त के साथ tidyr आप कर सकते हैं:

df.now %>%
 group_by(pair = paste(pmax(fit, sit), pmin(fit, sit), sep = "_")) %>%
 summarise_at(vars(starts_with("value")), ~ ifelse(all(is.na(.)), 
                                                   NA,
                                                   first(na.omit(.)))) %>%
 separate(pair, into = c("fit", "hit"), sep = "_", remove = FALSE)

  pair    fit   hit   value1 value2 value3
  <chr>   <chr> <chr>  <dbl>  <dbl>  <dbl>
1 it2_it1 it2   it1        1      3      2
2 it4_it3 it4   it3        2      3      4
3 it6_it5 it6   it5        5     NA      2
4 it9_it7 it9   it7       NA      4     NA

धन्यवाद! यह अच्छा काम करता है। मैं आइटम को अलग करने के विकल्प में जोड़ने की सराहना करता हूं।
हीदर क्लार्क

3

आईएनजी के !duplicated()बाद उपयोग करें sort

df.now[!duplicated(t(apply(df.now[, c("fit", "sit")], 1, sort))), ]
#       value1 value2 value3 fit   sit  
# [1,] "1"    NA     NA     "it1" "it2"
# [2,] "2"    "3"    "4"    "it3" "it4"
# [3,] "5"    NA     NA     "it5" "it6"
# [4,] NA     "4"    NA     "it7" "it9"

जल्दी उत्तर देने के लिए धन्यवाद। हालाँकि, यह समाधान मेरे द्वारा रखी जाने वाली जानकारी को हटा देता है। मैं एक ही आइटम जोड़े की 2 पंक्तियों में पाए जाने वाले 3 मूल्य स्तंभों से जानकारी को जोड़ना चाहता हूं। मुझे बताएं कि क्या यह स्पष्ट नहीं है
हीदर क्लार्क

2

से उपयोग कर melt/dcastरहे हैंdata.table

library(data.table)
dcast(melt(setDT(df.now)[, c('fit1', 'sit1') := .(pmin(fit, sit), 
    pmax(fit, sit))], measure = patterns("^value"), na.rm = TRUE),
     fit1 + sit1 ~ variable, value.var = 'value')
#   fit1 sit1 value1 value2 value3
#1:  it1  it2      1      3      2
#2:  it3  it4      2      3      4
#3:  it5  it6      5     NA      2
#4:  it7  it9     NA      4     NA

डेटा

df.now <- data.frame(value1,value2,value3, fit, sit, stringsAsFactors = FALSE)

2

एक अन्य data.tableविकल्प:

library(data.table)
as.data.table(df.now)[, lapply(.SD, function(x) first(x[!is.na(x)])), 
    .(it1=pmin(fit, sit), it2=pmax(fit, sit)), 
    .SDcols=value1:value3]

उत्पादन:

   it1 it2 value1 value2 value3
1: it1 it2      1      3      2
2: it3 it4      2      3      4
3: it5 it6      5   <NA>      2
4: it7 it9   <NA>      4   <NA>

1

यहाँ data.table का उपयोग करके मेरा प्रयास है। आपका डाटा कहा जाता है mydf। सबसे पहले, मैंने हल किया fitऔर sitप्रत्येक पंक्ति के लिए और एक नया चर बनाया group। फिर, प्रत्येक समूह के लिए, मैंने तीन मान स्तंभों (जैसे, value1, value2, और value3) में मानों को सॉर्ट किया। अंत में, मैंने प्रत्येक समूह के लिए पहली पंक्ति निकाली।

library(data.table)

mydt <- setDT(mydf)[, group := paste(sort(.SD), collapse = "_"),
                    .SD = c("fit", "sit"), by = 1:nrow(mydf)][,
                        c("value1", "value2", "value3") := lapply(.SD, sort),
                        .SDcols = value1:value3, by = group][, .SD[1], by = group]

mydt[]

#     group value1 value2 value3 fit sit
#1: it1_it2      1      3      2 it1 it2
#2: it3_it4      2      3      4 it3 it4
#3: it5_it6      5     NA      2 it5 it6
#4: it7_it9     NA      4     NA it7 it9

डेटा

mydf <- structure(list(value1 = c(1L, NA, 2L, NA, 5L, NA, NA), value2 = c(NA, 
3L, 3L, NA, NA, NA, 4L), value3 = c(NA, 2L, 4L, NA, NA, 2L, NA
), fit = c("it1", "it2", "it3", "it4", "it5", "it6", "it7"), 
sit = c("it2", "it1", "it4", "it3", "it6", "it5", "it9")), class = "data.frame", row.names = c(NA, 
-7L))

1

यह भी उपयोग किया जा सकता tidyr'एस pivot_longerके साथ values_drop_na = TRUEके साथ संयुक्त pivot_wider:

library(tidyverse)

mydf %>%
   mutate(it1 = pmin(fit, sit), it2 = pmax(fit, sit)) %>%
   pivot_longer(cols = starts_with("value"), values_drop_na = TRUE) %>%
   pivot_wider(id_cols = c("it1", "it2"))

#> # A tibble: 4 x 5
#>   it1   it2   value1 value2 value3
#>   <chr> <chr>  <int>  <int>  <int>
#> 1 it1   it2        1      3      2
#> 2 it3   it4        2      3      4
#> 3 it5   it6        5     NA      2
#> 4 it7   it9       NA      4     NA

डेटा

mydf <- structure(list(value1 = c(1L, NA, 2L, NA, 5L, NA, NA), value2 = c(NA, 
3L, 3L, NA, NA, NA, 4L), value3 = c(NA, 2L, 4L, NA, NA, 2L, NA
), fit = c("it1", "it2", "it3", "it4", "it5", "it6", "it7"), 
sit = c("it2", "it1", "it4", "it3", "it6", "it5", "it9")), class = "data.frame", row.names = c(NA, 
-7L))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.