2015-05-15 77 views
15

我想排除所有重複的行。但是,只有當它們是後續行時,它纔是真實的。遵循一個代表性的例子:排除後續的重複行

我輸入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) 

我的預期outdf

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) 

回答

14

rle()是一個很好的函數,用於標識相同值的運行,但將它的輸出轉換爲可用的形式可能有點痛苦。這是一個相對無痛咒語在你的情況下起作用。

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

有解決這個大概很多方面,我會嘗試從data.tabledevel version

rleid/unique組合
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 

或者從一些偉大的建議,由評論:

只需使用新shift功能

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

或者使用duplicatedrleid

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

這個怎麼樣結合:

> 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 

這裏,df[-nrow(df),-1] != df[-1,-1]查找包含不同值的連續行對,其餘代碼從數據幀中提取它們。

2

我遇到這個漂亮的功能,而前來到其國旗行作爲被首先基於一個指定的變量:

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 
    } 

把它應用到您的數據提供了:

> 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 

你然後可以在第一列上進行重複數據刪除以獲得您的預期輸出。

我發現這在過去非常有用,特別是來自SAS背景,這很容易做到。

4

我會使用類似@NPE的

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

當然你也可以使用任何其他公差等級(比1e-6等)的解決方案。

2

許多很好的答案已經,這裏是dplyr版本:

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