【发布时间】:2017-05-17 16:44:42
【问题描述】:
我有一个 data.table 说 dt
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)
看起来像:
> 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
我只需要那些遵循每个班级分数单调序列的记录。在这种情况下,只有 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: 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
为了找到单调的序列我试过了:
dt <- dt[, .SD[score == cummax(score)],class]
但这也删除了达到最大值后重新启动的序列。
实际上序列重启的最大值为 999999,虽然在这个例子中我取最大值为 99。我该怎么做。
【问题讨论】:
-
我不确定您的收录条件是否明确。你能尝试更明确一点吗?
-
序列必须是单调的,我需要从它们之间删除任何乱序,同时还必须注意序列重启
-
dt[, keep := score >= cummax(shift(score, fill = first(score))), by = .(class, rleid(score == 99))]还要注意单调序列,最大化条件,但它正在从类 c1 中删除第 3 行到第 7 行,因为前面提到了分数 82,尽管那是无序的,必须删除
-
例如,我们怎么知道从
c3中排除76?选择序列最低元素的条件是什么? -
每个类的第一个元素是最低的,否则我们看上一个类的前几个seq
标签: r dataframe data.table