找到单调的序列以及在达到最大值时重新启动序列

时间:2017-05-17 16:44:43

标签: r dataframe data.table

我有一个data.table说dt

to_char(to_timestamp(act_veh.whse_lbr_tran_datetime::text, 'YYYYMMDDHH24MISS'), 'HH:MI:SS AM')

看起来像:

name <- letters[1:22]
score <- c(42, 82, 43, 32, 47, 48, 49, 50, 54, 59, 
           76, 9, 13, 88, 91, 99, 4, 6, 8, 12, 14, 15)
class <- rep(c('c1', 'c2', 'c3'), c(7, 3, 12))
dt <- data.table(name, score, class)

我只需要那些遵循每个班级单调的分数顺序的记录。在这种情况下,对于类c1,只有得分为42,43,47,48 49的记录,对于给定的类,最多可以有3个连续的无序分数。第2行(得分= 82)因此也是无序分数。

对于c2类,得分为50,54,59的记录。

在“c3”类记录中得分为76,88,91,99,04,06,08,12,14,15。此处序列已达到最大值(99),然后重新启动。 “c3”类中的得分09和13不符合单调序列,因此需要将其删除。

我想删除那些记录中提到的分数不是c1,c2,c3类的每个记录的记录。总共有100万条记录。

最终输出必须如下。

> dt
    name score class
 1:    a    42    c1
 2:    b    82    c1
 3:    c    43    c1
 4:    d    32    c1
 5:    e    47    c1
 6:    f    48    c1
 7:    g    49    c1
 8:    h    50    c2
 9:    i    54    c2
10:    j    59    c2
11:    k    76    c3
12:    l     9    c3
13:    m    13    c3
14:    n    88    c3
15:    o    91    c3
16:    p    99    c3
17:    q     4    c3
18:    r     6    c3
19:    s     8    c3
20:    t    12    c3
21:    u    14    c3
22:    v    15    c3

为了找到单调的序列,我试过了:

> dt
    name score class
 1:    a    42    c1
 2:    c    43    c1
 3:    e    47    c1
 4:    f    48    c1
 5:    g    49    c1
 6:    h    50    c2
 7:    i    54    c2
 8:    j    59    c2
 9:    k    76    c3
10:    n    88    c3
11:    o    91    c3
12:    p    99    c3
13:    q     4    c3
14:    r     6    c3
15:    s     8    c3
16:    t    12    c3
17:    u    14    c3
18:    v    15    c3

但这也是删除在达到最大值后重新启动的序列。

实际上,如果是999999,序列重启的最大值,不过对于这个例子,我最大值为99.我怎么能这样做。

1 个答案:

答案 0 :(得分:0)

这主要可以使用dplyr

来完成
dts <- dt %>% 
       group_by(class) %>% 
       mutate(f = ifelse( (score - lead(score) > 0 & lag(score) - score <0) | 
                          (score - lead(score) < 0 & lag(score) - score > 0) , 1, 0)) %>%
       mutate(f = ifelse(is.na(f), 0, f)) %>%
       mutate(g = ifelse((lead(f) == 1 & f == 1)| (lag(f) == 1 & f == 1 ), 2, 0) )) %>%
       filter(f + g != 1)

正如我所说,这将主要让你到达那里。这个问题是你会得到19个观察结果(保留id = m)而不是18个。你可以做的是在dts上重新运行它以消除id = m。或者,如果这是较大集的子集,则可以使用forwhile循环。这是因为leadlag函数只检查上面和下面的一个索引。

另一个选择是一种古老的学校技术,称为推 - 流技术,但我会远离它。