我有一个数据框,其中一列包含一些连续的重复项。我想保留连续重复的行(任何长度> 1)。我希望使用dplyr
或data.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
谢谢!
答案 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}}和ave
到subset
行
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 ~