R - 删除连续(仅)重复项

ebb*_*ebb 5 r duplicates repeat delete-row

我需要根据给定列中值的重复来消除数据帧中的行,但只需要连续的那些行.例如,对于以下数据框:

df = data.frame(x=c(1,1,1,2,2,4,2,2,1))
df$y <- c(10,11,30,12,49,13,12,49,30)
df$z <- c(1,2,3,4,5,6,7,8,9)

x  y z
1 10 1
1 11 2
1 30 3
2 12 4
2 49 5
4 13 6
2 12 7
2 49 8
1 30 9
Run Code Online (Sandbox Code Playgroud)

我需要在x列中消除具有连续重复值的行,保留最后重复的行,并保持数据帧的结构:

x  y z
1 30 3
2 49 5
4 13 6
2 49 8
1 30 9
Run Code Online (Sandbox Code Playgroud)

按照指示help和其他一些帖子,我尝试使用该duplicated功能:

df[ !duplicated(x,fromLast=TRUE), ] # which gives me this:
      x  y  z
1     1 10  1
6     4 13  6
7     2 12  7
9     1 30  9
NA   NA NA NA
NA.1 NA NA NA
NA.2 NA NA NA
NA.3 NA NA NA
NA.4 NA NA NA
NA.5 NA NA NA
NA.6 NA NA NA
NA.7 NA NA NA
NA.8 NA NA NA
Run Code Online (Sandbox Code Playgroud)

不知道为什么我在最后得到NA行(没有发生我正在测试的类似表),但只对部分值有效.

我也试过使用data.table如下包:

library(data.table)
dt <- as.data.table(df)           
setkey(dt, x)                    
dt[J(unique(x)), mult ='last'] 
Run Code Online (Sandbox Code Playgroud)

效果很好,但它消除了数据框中的所有重复项,而不仅仅是那些连续的重复项,给出了类似这样的内容:

x  y z
1 30 9
2 49 8
4 13 6
Run Code Online (Sandbox Code Playgroud)

请原谅,如果交叉发布.我尝试了一些建议,但没有一个只能消除那些连续的建议.我将不胜感激任何帮助.

谢谢

ngm*_*ngm 7

怎么样:

df[cumsum(rle(df$x)$lengths),]
Run Code Online (Sandbox Code Playgroud)

说明:

rle(df$x)
Run Code Online (Sandbox Code Playgroud)

为您提供变量中连续重复项的运行长度和值x.然后:

rle(df$x)$lengths
Run Code Online (Sandbox Code Playgroud)

提取长度.最后:

cumsum(rle(df$x)$lengths)
Run Code Online (Sandbox Code Playgroud)

给出可以使用的行索引[.

编辑乐趣这里是microbenchmark迄今为止给出的答案rle,consec是我的答案,我认为是@James给出的最基本的直接答案,并且是我将"接受" dpdplyr答案,并且是@Nik给出的答案.

#> Unit: microseconds
#>    expr       min         lq       mean     median         uq        max
#>     rle   134.389   145.4220   162.6967   154.4180   172.8370    375.109
#>  consec   111.411   118.9235   136.1893   123.6285   145.5765    314.249
#>      dp 20478.898 20968.8010 23536.1306 21167.1200 22360.8605 179301.213
Run Code Online (Sandbox Code Playgroud)

rle 表现比我想象的要好.


Jam*_*mes 6

您只需要检查一个数字后面没有重复,即x [i + 1]!= x [i]并注意最后一个值将始终存在.

df[c(df$x[-1] != df$x[-nrow(df)],TRUE),]
  x  y z
3 1 30 3
5 2 49 5
6 4 13 6
8 2 49 8
9 1 30 9
Run Code Online (Sandbox Code Playgroud)