如果观察连续出现,则删除重复项,顺序很重要

时间:2019-06-14 04:28:15

标签: r duplicates

我有一个按Bikeid分组并按时间排序的数据框。如果类型连续重复,我想保留最早的时间。在以下情况下,我要删除第17、19、33、39和41行

subtract value from previous row by group 删除重复项后,这将满足我的需要。

    bikeid    type              time
1   1004    repair_time 2019-04-04 14:07:00
3   1004    red_time    2019-04-19 00:54:56
8   1004    repair_time 2019-04-19 12:47:00
10  1004    red_time    2019-04-19 16:45:18
15  1004    repair_time 2019-04-20 04:42:00
17  1004    repair_time 2019-04-20 05:29:00
19  1004    repair_time 2019-04-28 07:33:00
27  1010    repair_time 2019-04-20 10:05:00
29  1010    red_time    2019-04-22 20:51:21
33  1010    red_time    2019-04-23 11:02:34
37  1010    repair_time 2019-04-24 17:20:00
39  1010    repair_time 2019-04-24 18:30:00
41  1010    repair_time 2019-04-24 18:42:00

最终结果应如下所示:

   bikeid    type              time
1   1004    repair_time 2019-04-04 14:07:00
3   1004    red_time    2019-04-19 00:54:56
8   1004    repair_time 2019-04-19 12:47:00
10  1004    red_time    2019-04-19 16:45:18
15  1004    repair_time 2019-04-20 04:42:00
27  1010    repair_time 2019-04-20 10:05:00
29  1010    red_time    2019-04-22 20:51:21
37  1010    repair_time 2019-04-24 17:20:00

2 个答案:

答案 0 :(得分:3)

一种选择是使用rleid(来自data.table)来创建分组变量,以及第二列和slice第一个观察值。在这里,时间列已经arrange d,所以我们不必进行任何排序

library(dplyr)
library(data.table)
df1 %>%
    group_by(V2, grp = rleid(V3)) %>%
    slice(1) %>%
    ungroup %>%
    select(-grp)
# A tibble: 8 x 4
#     V1    V2 V3          V4                 
#  <int> <int> <chr>       <chr>              
#1     1  1004 repair_time 2019-04-04 14:07:00
#2     3  1004 red_time    2019-04-19 00:54:56
#3     8  1004 repair_time 2019-04-19 12:47:00
#4    10  1004 red_time    2019-04-19 16:45:18
#5    15  1004 repair_time 2019-04-20 04:42:00
#6    27  1010 repair_time 2019-04-20 10:05:00
#7    29  1010 red_time    2019-04-22 20:51:21
#8    37  1010 repair_time 2019-04-24 17:20:00

或使用data.table方法将“ data.frame”转换为 由'V2'和'V3'的setDT(df1)分组的'data.table'(rleid),获得第一个观测值的行索引(.I),提取({{ 1}}),并将数据集的行作为子集

$V1

数据

library(data.table)
setDT(df1)[df1[, .I[1], .(V2, rleid(V3))]$V1]

答案 1 :(得分:3)

另一个使用lag来检查状态是否与上一行相同的选项。如akrun所述,这是可行的,因为数据已按时间排序:

library(dplyr)

df %>%
    group_by(bikeid) %>%
    mutate(repeated = status == lag(status)) %>%
    # Need the is.na() check as first element of each group is NA
    #   due to the lag
    filter(! repeated | is.na(repeated))

数据设置代码:

txt = "1   1004    repair_time 2019-04-04 14:07:00
3   1004    red_time    2019-04-19 00:54:56
8   1004    repair_time 2019-04-19 12:47:00
10  1004    red_time    2019-04-19 16:45:18
15  1004    repair_time 2019-04-20 04:42:00
17  1004    repair_time 2019-04-20 05:29:00
19  1004    repair_time 2019-04-28 07:33:00
27  1010    repair_time 2019-04-20 10:05:00
29  1010    red_time    2019-04-22 20:51:21
33  1010    red_time    2019-04-23 11:02:34
37  1010    repair_time 2019-04-24 17:20:00
39  1010    repair_time 2019-04-24 18:30:00
41  1010    repair_time 2019-04-24 18:42:00"

df = read.table(text = txt, header = FALSE)
colnames(df) = c("row", "bikeid", "status", "date", "time")
df$date = as.POSIXct(paste(df$date, df$time))