2015-05-15 14 views
15

Ich möchte alle duplizierten Zeilen ausschließen. Es muss jedoch nur dann wahr sein, wenn es sich um nachfolgende Zeilen handelt. Folgt ein repräsentatives Beispiel:Nachfolgende doppelte Zeilen ausschließen

Mein Eingang df:

df <- "NAME VALUE 
    Prb1 0.05 
    Prb2 0.05 
    Prb3 0.05 
    Prb4 0.06 
    Prb5 0.06 
    Prb6 0.01 
    Prb7 0.10 
    Prb8 0.05" 

df <- read.table(text=df, header=T) 

Mein outdf erwartet:

outdf <- "NAME VALUE 
Prb1 0.05 
Prb4 0.06 
Prb6 0.01 
Prb7 0.10 
Prb8 0.05" 

outdf <- read.table(text=df, header=T) 

Antwort

14

rle() ist eine nette Funktion, die Läufe mit identischen Werten identifiziert, aber es kann ein bisschen schmerzhaft sein, seine Ausgabe in eine brauchbare Form zu bringen. Hier ist eine relativ schmerzlose Beschwörung, die in Ihrem Fall funktioniert.

df[sequence(rle(df$VALUE)$lengths) == 1, ] 
# NAME VALUE 
# 1 Prb1 0.05 
# 4 Prb4 0.06 
# 6 Prb6 0.01 
# 7 Prb7 0.10 
# 8 Prb8 0.05 
10

Es gibt wahrscheinlich viele Wege zur Lösung dieses, würde ich rleid/unique Kombination aus den data.tabledevel version

versuchen
library(data.table) ## v >= 1.9.5 
unique(setDT(df)[, indx := rleid(VALUE)], by = "indx") 
# NAME VALUE indx 
# 1: Prb1 0.05 1 
# 2: Prb4 0.06 2 
# 3: Prb6 0.01 3 
# 4: Prb7 0.10 4 
# 5: Prb8 0.05 5 

Oder von einigen großen Anregungen Kommentare:

gerade die neue shift Funktion

setDT(df)[VALUE != shift(VALUE, fill = TRUE)] 

Oder duplicated mit rleid

kombiniert mit Verwendung
setDT(df)[!duplicated(rleid(VALUE)), ] 
8

Wie wäre es damit:

> df[c(T, df[-nrow(df),-1] != df[-1,-1]), ] 
    NAME VALUE 
1 Prb1 0.05 
4 Prb4 0.06 
6 Prb6 0.01 
7 Prb7 0.10 
8 Prb8 0.05 

Hier findet df[-nrow(df),-1] != df[-1,-1] Paare aufeinanderfolgender Zeilen, die unterschiedliche Werte enthalten, und der Rest des Codes extrahiert sie aus dem Datenrahmen.

2

Ich kam in dieses nette Funktion eine Weile her, welche Flags Reihen als erste auf einer bestimmten Variablen basiert:

> df$first <- isFirst(df$VALUE) 
> df 
    NAME VALUE first 
1 Prb1 0.05 TRUE 
2 Prb2 0.05 FALSE 
3 Prb3 0.05 FALSE 
4 Prb4 0.06 TRUE 
5 Prb5 0.06 FALSE 
6 Prb6 0.01 TRUE 
7 Prb7 0.10 TRUE 
8 Prb8 0.05 TRUE 

Sie:

isFirst <- function(x,...) { 
     lengthX <- length(x) 
     if (lengthX == 0) return(logical(0)) 
     retVal <- c(TRUE, x[-1]!=x[-lengthX]) 
     for(arg in list(...)) { 
      stopifnot(lengthX == length(arg)) 
      retVal <- retVal | c(TRUE, arg[-1]!=arg[-lengthX]) 
     } 
     if (any(missing<-is.na(retVal))) # match rle: NA!=NA 
      retVal[missing] <- TRUE 
     retVal 
    } 

es auf Ihre Daten anwenden gibt kann dann auf die erste Spalte deduplizieren, um Ihre erwartete Ausgabe zu erhalten.

Ich habe das in der Vergangenheit sehr nützlich gefunden, vor allem aus einem SAS-Hintergrund, wo dies sehr einfach war.

4

würde ich eine Lösung ähnlich wie @NPE ‚s

df[c(TRUE,abs(diff(df$VALUE))>1e-6),] 

Natürlich verwenden Sie eine andere Toleranzniveau (außer 1e-6) verwenden können.

2

Viele gute Antworten schon, hier ist dplyr Version:

filter(df,VALUE!=lag(VALUE,default=df$VALUE[1]+1))