保持连续重复

时间:2019-10-21 14:13:40

标签: r dplyr data.table

我有一个数据框,其中一列包含一些连续的重复项。我想保留连续重复的行(任何长度> 1)。我希望使用dplyrdata.table中的解决方案。

示例数据:

a <- seq(10,150,10)
b <- c("A", "A", "B", "C", "C", "A", "B", "B", "B", "C", "A", "C", "D", "E", "E")

df <- tibble(a, b)

数据:

# A tibble: 15 x 2
       a b    
   <dbl> <chr>
 1    10 A    
 2    20 A    
 3    30 B    
 4    40 C    
 5    50 C    
 6    60 A    
 7    70 B    
 8    80 B    
 9    90 B    
10   100 C    
11   110 A    
12   120 C    
13   130 D    
14   140 E    
15   150 E 

所以我想将具有连续重复项的行保留在列b中。

预期结果:

# A tibble: 9 x 2
       a b    
   <dbl> <chr>
 1    10 A    
 2    20 A    
 4    40 C    
 5    50 C    
 7    70 B    
 8    80 B    
 9    90 B          
14   140 E    
15   150 E 

谢谢!

7 个答案:

答案 0 :(得分:2)

使用末尾注释中显示的data.table输入,将N设置为每组连续元素中的元素数,然后保留大于1的组。

DT[, N :=.N, by = rleid(b)][N > 1, .(a, b)]

给予:

     a b
1:  10 A
2:  20 A
3:  40 C
4:  50 C
5:  70 B
6:  80 B
7:  90 B
8: 140 E
9: 150 E

注意

我们假定可重复输入的形式为:

library(data.table)
a <- seq(10,150,10)
b <- c("A", "A", "B", "C", "C", "A", "B", "B", "B", "C", "A", "C", "D", "E", "E")
DT <- data.table(a, b)

答案 1 :(得分:0)

由于您还具有data.table标签,因此我喜欢将data.table::rleid函数用于此类任务,即

library(dplyr)

df %>% 
 group_by(grp = data.table::rleid(b), b) %>% 
 filter(n() > 1)

给出,

# A tibble: 9 x 3
# Groups:   grp, b [4]
      a b       grp
  <dbl> <chr> <int>
1    10 A         1
2    20 A         1
3    40 C         3
4    50 C         3
5    70 B         5
6    80 B         5
7    90 B         5
8   140 E        10
9   150 E        10

答案 2 :(得分:0)

dplyr中,我们可以使用lag创建组并选择多于1行的组。

library(dplyr)

df %>%
  group_by(group = cumsum(b != lag(b, default = first(b)))) %>%
  filter(n() > 1) %>%
  ungroup() %>%
  select(-group)

#     a  b    
#  <dbl> <chr>
#1    10 A    
#2    20 A    
#3    40 C    
#4    50 C    
#5    70 B    
#6    80 B    
#7    90 B    
#8   140 E    
#9   150 E  

在基数R中,我们可以使用rle的{​​{1}}和avesubset

df

答案 3 :(得分:0)

除了连续的情况外,您要删除重复的内容:以下代码标记重复的值和连续的值,然后仅保留非重复的行或连续重复的一部分的行。

let date, end;

date = new Date()
end = new Date(date.getFullYear(), date.getMonth() + 1, 0)

console.log(end) // prints: Thu Oct 31 2019 00:00:00 GMT-0300 (Horário Padrão de Brasília)
console.log(end.getDay()) // prints: 4

答案 4 :(得分:0)

使用rle来获得行程长度。

假设df <- data.frame(a=a,b=b),则以下内容可以实现

df[-cumsum(rle(b)$lengths)[rle(b)$lengths==1],]

答案 5 :(得分:0)

另一种解决方案同时利用了lead()lag()

library(tidyverse)

a <- seq(10,150,10)
b <- c("A", "A", "B", "C", "C", "A", "B", "B", "B", "C", "A", "C", "D", "E", "E")

df <- tibble(a, b)

df %>% filter(b == lead(b) | b == lag(b))
#> # A tibble: 9 x 2
#>       a b    
#>   <dbl> <chr>
#> 1    10 A    
#> 2    20 A    
#> 3    40 C    
#> 4    50 C    
#> 5    70 B    
#> 6    80 B    
#> 7    90 B    
#> 8   140 E    
#> 9   150 E

reprex package(v0.3.0)于2019-10-21创建

答案 6 :(得分:0)

这是另一个选择(应该更快):

D[-D[, {
    x <- rowid(rleid(b)) < 2
    .I[x & shift(x, -1L, fill=TRUE)]
}]]

计时代码:

library(data.table)
set.seed(0L)
nr <- 1e7
nb <- 1e4
DT <- data.table(b=sample(nb, nr, TRUE))
#DT <- data.table(b=c("A", "A", "B", "C", "C", "A", "B", "B", "B", "C", "A", "C", "D", "E", "E"))
DT2 <- copy(DT)

mtd1 <- function(df) {
    df[-cumsum(rle(b)$lengths)[rle(b)$lengths==1],]
}

mtd2 <- function(D) {
    D[, N :=.N, by = rleid(b)][N > 1, .(b)]
}

mtd3 <- function(D) {
    D[-D[, {
        x <- rowid(rleid(b)) < 2
        .I[x & shift(x, -1L, fill=TRUE)]
    }]]
}

bench::mark(mtd1(DT), mtd2(DT2), mtd3(DT), check=FALSE)

时间:

# A tibble: 3 x 13
  expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result             memory          time    gc            
  <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> <list>             <list>          <list>  <list>        
1 mtd1(DT)       1.1s     1.1s     0.908    1.98GB    10.9      1    12       1.1s <df[,1] [2,014 x ~ <df[,3] [59 x ~ <bch:t~ <tibble [1 x ~
2 mtd2(DT2)     2.88s    2.88s     0.348  267.12MB     0        1     0      2.88s <df[,1] [2,014 x ~ <df[,3] [23 x ~ <bch:t~ <tibble [1 x ~
3 mtd3(DT)   639.91ms 639.91ms     1.56   505.48MB     4.69     1     3   639.91ms <df[,1] [2,014 x ~ <df[,3] [24 x ~ <bch:t~ <tibble [1 x ~