繁体   English   中英

排除后续重复的行

[英]Exclude subsequent duplicated rows

我想排除所有重复的行。 但是,只有当它们是后续行时才必须如此。 遵循一个代表性的例子:

我的输入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)

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

可能有很多方法可以解决这个问题,我会尝试使用data.table devel版本中的 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)]

或者使用duplicated结合rleid

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

这个怎么样:

> 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]查找包含不同值的连续行对,其余代码从数据帧中提取它们。

我会使用类似于@NPE的解决方案

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

当然,您可以使用任何其他容差级别( 1e-6除外)。

我刚才遇到了这个很好的函数,它首先根据指定的变量标记行:

  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背景,这很容易做到。

已有很多好的答案,这里是dplyr版本:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM