"Daha küçük aboneliklere sahip öğeler" dahil olmak üzere TÜM yinelenen satırları bulma


111

R'ın duplicateddöner bir vektör ya da veri çerçevesinin her eleman daha küçük bir simge olmayan bir elemanının bir kopyası olup olmadığını gösteren bir vektör. Yani 5 satırlık bir veri çerçevesinin 3, 4 ve 5 satırları aynıysa, duplicatedbana vektörü verecek

FALSE, FALSE, FALSE, TRUE, TRUE

Ama bu durumda gerçekten almak istiyorum

FALSE, FALSE, TRUE, TRUE, TRUE

yani, bir satırın daha büyük bir alt simgeye sahip bir satır tarafından çoğaltılıp çoğaltılmadığını bilmek istiyorum .

Yanıtlar:


128

duplicatedbir fromLasttartışması var. "Örnek" bölümü ?duplicated, onu nasıl kullanacağınızı gösterir. Sadece duplicatediki kez, bir kez ile fromLast=FALSEve bir kez ile arayın fromLast=TRUEve her ikisini de arayın TRUE.


Geç Düzenleme: Tekrarlanabilir bir örnek sağlamadınız, işte @jbaums tarafından nazikçe katkıda bulunulan bir örnek

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

Düzenleme: Ve bir veri çerçevesi durumu için bir örnek:

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
Bekle, sadece bir test yaptım ve yanıldığımı anladım: 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, 8 ve 9 kopyalarının üçünü de geri verdim . Bu neden çalışıyor?
JoeM05

1
Çünkü ortadaki olanlar, ister sondan ister önden başlasanız da yakalanır. Örneğin, duplicated(c(1,1,1))vs duplicated(c(1,1,1,), fromLast = TRUE)verir c(FALSE,TRUE,TRUE)ve c(TRUE,TRUE,FALSE). TRUEHer iki durumda da orta değer . |Her iki vektörün alınması da verir c(TRUE,TRUE,TRUE).
Brandon

34

Değer kümesini bir araya duplicatedgetirmeniz, uygulamanız uniqueve ardından ile test etmeniz gerekir %in%. Her zaman olduğu gibi, örnek bir problem bu süreci canlandıracaktır.

> 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

Katılıyorum. İşlemeyi bile yavaşlatabilir, ancak muhtemelen çok fazla yavaşlamaz.
IRTFM

Sessiz doğru. OP, bir veri çerçevesindeki "hiç çoğaltılmış" satırları test etmek için bir veri örneği sunmadı. Ben kullanmanın benim önerim düşünüyorum duplicated, uniqueve %in%bir ilk olsaydı kolayca dataframe için genelleştirilmiş olabilir pastealışılmadık bir ayırıcı karakteri ile her satır. (Kabul edilen cevap daha iyi.)
IRTFM

3

Ben de aynı soruyu sordum ve yanılmıyorsam, bu da bir cevap.

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

Dunno, hangisi daha hızlı olsa da, şu anda kullandığım veri kümesi, önemli zaman boşlukları üreten testler yapacak kadar büyük değil.


1
Bu cevap vechem atomik vektör hem de veri çerçevesi olarak kullanılıyor gibi görünüyor . Gerçek bir datframe ile başarısız olacağından şüpheleniyorum.
IRTFM

3

Bir dataframe çoğaltılmış satırlar ile elde edilebilir dplyryaparak

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

Verileri group_by_at(vars(-var1, -var2))gruplamak yerine belirli sütunları hariç tutmak için kullanılabilir.

Yalnızca veriler değil de satır dizinleri gerçekten gerekliyse, bunları ilk önce şu şekilde ekleyebilirsiniz:

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

1
Güzel kullanım n(). Ortaya çıkan veri çerçevesinin grubunu çözmeyi unutmayın.
qwr

@qwr Sonucu grubunu çözmek için yanıtı ayarladım
Holger Brandl

2

İşte @Joshua Ulrich'in bir fonksiyon olarak çözümü. Bu biçim, bu kodu duplicated () kullanacağınız şekilde kullanmanıza izin verir:

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

Aynı örneği kullanarak:

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

0

Belirli sütunlar için hangi satırların çoğaltıldığıyla ilgileniyorsanız, bir plyr yaklaşımı kullanabilirsiniz :

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

Dplyr ile bir count değişkeni eklemek :

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

Yinelenen satırlar için (tüm sütunlar dikkate alınarak):

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

Bu yaklaşımların yararı, kaç tane kopyayı bir kesme olarak belirtebilmenizdir.


0

Benzer bir sorun yaşadım, ancak yinelenen satırları belirli sütunlardaki değerlere göre tanımlamam gerekiyordu. Aşağıdaki dplyr çözümünü buldum :

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

Kod, satırları belirli sütunlara göre gruplandırır. Bir grubun uzunluğu 1'den büyükse, kod gruptaki tüm satırları çoğaltılmış olarak işaretler. Bu yapıldıktan sonra Duplicatedfiltreleme vb. İçin sütunu kullanabilirsiniz .

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.