2013-07-15 6 views
6

Come rimuovere le voci duplicate consecutive in R? Penso che possa essere usato with ma non riesco a pensare a come usarlo. Illustrando un esempio: i datiRimuovere le voci duplicate consecutive

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

Esempio: D

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

richiesto Risultato:

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

`

risposta

0

Una soluzione in base di R con split-apply-combine opere tramite la funzione tail che restituisce l'ultimo elemento e rle in combinazione con mapply per creare un nuovo vettore di events che conserva l'ordine in caso di eventi ricompaiono:

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) 

Questo produce l'uscita desiderata.

+0

Grazie per l'aiuto, ma c'è una leggera modifica nella domanda. Inoltre l'ordine rimane lo stesso nell'uso di 'tail'? Ho provato questo e si sta ordinando gli eventi in ordine alfabetico. – anu

+0

@anu si prega di vedere il mio aggiornamento, dovrebbe funzionare ora. – Henrik

2

MODIFICA: non esattamente corretta poiché mostra solo una riga b. È inoltre possibile utilizzare il duplicato() funzione

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

Questo è vicino, ma non dà assolutamente il risultato previsto dell'OP. Non ho mai saputo di 'fromLast = TRUE' sebbene - abbastanza pulito. – thelatemail

+0

Oh dannazione! C'erano due b file! – Xachriel

12

ancora un altro, supponendo che il data.frmae si chiama 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 Questa sarebbe stata anche la mia risposta. Ho letto la domanda OP e quando hanno detto * rimuovere le voci duplicate consecutive * Ho pensato di prendere il primo di ciascuna usando 'cumsum (rle (df $ Event) lunghezze $) - rle (df $ Event) $ lunghezze + 1' –

+0

+ 1, decisamente migliore della mia combinazione piuttosto impegnativa di 'rle',' mapply', 'split',' tail', 'do.call', ... – Henrik

0

E per buona misura, utilizzando head e 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