我有一个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.我怎么能这样做。
答案 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
。或者,如果这是较大集的子集,则可以使用for
或while
循环。这是因为lead
和lag
函数只检查上面和下面的一个索引。
另一个选择是一种古老的学校技术,称为推 - 流技术,但我会远离它。