r'deki yinelenen satırları belirleme ve işaretleme


11

2 sütuna göre yinelenen satırları tanımlamak ve işaretlemek istiyorum. Her satır için benzersiz bir tanımlayıcı yapmak istiyorum, bu yüzden sadece satırın bir kopya olduğunu değil, aynı satırın bir kopya olduğunu biliyorum. Aşağıda bazı yinelenen öğe çiftleri (uygun ve oturmak) ve çoğaltılmamış diğer çiftleri ile benzeyen bir veri çerçevesi var. Öğe çiftleri çoğaltılırken içerdikleri bilgiler benzersizdir (örneğin, bir satır 1 satır için Değer1'de bir değere sahip olur, ancak Değer2 ve Değer 3 değil, ikinci veya 'yinelenen' satırda yalnızca Değer2 ve Değer3 için sayılar bulunur Değer Değil1)

mevcut veri çerçevesi

     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"

veri çerçevesi oluşturmak için kod

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)

ne istiyorum böyle bir veri çerçevesine dönüştürmek için:

istenen veri çerçevesi

     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"

Aşağıdaki adımları yapmayı düşünüyordum: 1. yinelenen çiftleri tanımlamak için en düşük öğe ve en yüksek öğeleri ile uyum ve oturmak kullanarak yeni değişkenler oluşturmak 2. yinelenen öğe çiftlerini tanımlamak 3. benzersiz bilgileri seçmek ve doldurmak için ifelse kullanın.

Adım 1 ve 3'ü nasıl yapacağımı biliyorum, ancak adım 2'de takılı kalıyorum. Yapmam gereken şey sadece DOĞRU / YANLIŞ kopyayı tanımlamak değil, belki de bu gibi her öğe çifti için benzersiz bir tanımlayıcıya sahip bir sütun var (orada 1. adımım nedeniyle 2 ekstra satır var):

     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

Bunu nasıl yapacağımdan emin değilim.

İstediğim şey, ya 2. adımla ilgili yardım ya da belki de çözdüğüm adımlardan daha iyi bir yol var.

Yanıtlar:


6

Bir dplyrseçenek olabilir:

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

Ve ayrıca tek tek sütunlarda çiftlere ihtiyacınız varsa, o zaman ekleyerek tidyrşunları yapabilirsiniz:

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

Teşekkür ederim! Bu iyi çalışıyor. Öğeleri ayırma seçeneğini eklemeyi takdir ediyorum.
Heather Clark

3

İng !duplicated()sonra kullanın 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"

Hızlı yanıt için teşekkürler. Ancak, bu çözüm saklamam gereken bilgileri siler. Aynı öğe çiftlerinin 2 satırında bulunan 3 değer sütunlarından bilgi birleştirmek istiyorum. Bu açık değilse bana bildirin
Heather Clark

2

Şuradan kullanma 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

veri

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

2

Başka bir data.tableseçenek:

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]

çıktı:

   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

İşte data.table kullanma girişimim. Verileriniz çağrılır mydf. İlk olarak, her sıra için sıraladım fitve sityeni bir değişken yarattım group. Sonra, her grup için, değerleri üç değer sütununda (yani değer1, değer2 ve değer3) sıraladım. Sonunda, her grup için ilk satırı çıkardım.

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

VERİ

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

Bu aynı zamanda kullanılarak yapılabilir tidyr's pivot_longerile values_drop_na = TRUEkombine 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

Veri

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