2013-07-15 38 views
6

Jak usunąć kolejne duplikaty wpisów w R? Myślę, że można użyć with, ale nie mogę myśleć, jak z niego korzystać. Ilustrujący jeden przykład: daneUsuwanie kolejnych duplikatów wpisów

read.table(text = " 
    a  t1 
    b  t2 
    b  t3 
    b  t4 
    c  t5 
    c  t6 
    b  t7 
    d  t8") 

próbki: D

events time 
     a  t1 
     b  t2 
     b  t3 
     b  t4 
     c  t5 
     c  t6 
     b  t7 
     d  t8 

Wymagane Rezultat:

 events  time 
     a  t1 
     b  t4 
     c  t6 
     b  t7 
     d  t8 

`

Odpowiedz

0

roztworu w podstawowej R za pomocą split-apply-połączyć prace poprzez funkcja tail, która zwraca ostatni element i rle w połączeniu z mapply aby utworzyć nowy wektor events który pozwala zachować porządek w przypadku zdarzeń pojawiając:

x <- read.table(text = " events time 
     a  t1 
     b  t2 
     b  t3 
     b  t4 
     c  t5 
     c  t6 
     b  t7 
     d  t8", header = TRUE) 


# create vector of new.events (i.e., preserve reappearing objects) 
occurences <- rle(as.character(x$events))[["lengths"]] 
new.events <- unlist(mapply(rep, x = letters[seq_along(occurences)], times = occurences)) 

# split into sublists per event 
s1 <- split(x, list(new.events)) 

# get last element from list 
s2 <- lapply(s1, tail, n = 1) 

# combine again 
do.call(rbind, s2) 

To daje pożądany wynik.

+0

Dziękuję za pomoc, ale jest niewielka zmiana w pytaniu. Czy kolejność jest taka sama w użyciu 'tail'? Próbowałem tego i sortuje wydarzenia w kolejności alfabetycznej. – anu

+0

@ proszę zobacz moją aktualizację, powinien działać teraz. – Henrik

2

EDYCJA: Nieprawidłowo, ponieważ pokazuje tylko jeden wiersz b. Można również użyć kopiowane() funkcji

x <- read.table(text = " events time 
    a  t1 
    b  t2 
    b  t3 
    b  t4 
    c  t5 
    c  t6 
    d  t7", header = TRUE) 
#Making sure the data is correctly ordered! 
x <- x[order(x[,1], x[,2]), ]  
x[!duplicated(x[,1], fromLast=TRUE), ] 
+0

Jest to bliskie, ale nie daje dość zamierzonego rezultatu PO. Jednak nigdy nie wiedziałem o 'fromLast = TRUE' - całkiem zgrabnym. – thelatemail

+0

O cholera! Były dwa rzędy b! – Xachriel

12

Jeszcze inny drugi, zakładając, że data.frmae nazwie d:

d[cumsum(rle(as.numeric(d[,1]))$lengths),] 
    V1 V2 
1 a t1 
4 b t4 
6 c t6 
7 b t7 
8 d t8 
+0

+1 To też była moja odpowiedź. Przeczytałem pytanie OP i kiedy powiedzieli * usuń kolejne duplikaty wpisów * Pomyślałem, że biorę pierwsze z każdego używając 'cumsum (rle (df $ Event) $ lengths) - rle (df $ Event) $ lengths + 1' –

+0

+ 1, zdecydowanie lepiej niż moja nieco trudna kombinacja 'rle',' mapply', 'split',' tail', 'do.call', ... – Henrik

0

A na dokładkę, za pomocą head i tail:

dat[with(dat,c(tail(events,-1) != head(events,-1),TRUE)),] 

    events time 
1  a t1 
4  b t4 
6  c t6 
7  b t7 
8  d t8 
Powiązane problemy