我目前正在处理一辆车的数据。我们每5分钟记录一次汽车的速度,它包含了大量的零值。我的问题是,如何将数据分割成一个零值,并在R中给每个非零段一个有序数?让我们以一个示例数据为例:
sample <- data.frame(
id = 1:15,
speed = c(50,0, 0, 30, 50, 40,0, 0, 25, 30, 50, 0, 30, 50, 40))我想添加一个新列,为每个非零部分提供一个数字(从1开始),而是一个连续的k-零速度(或更多)编号为0。特别是对于这个示例数据,假设k等于2,那么我想要的结果应该类似于这个dataframe:
sample_new <- data.frame(
id = 1:15,
speed = c(50,0, 0, 0, 50, 40,0, 0, 25, 30, 50, 0, 30, 50, 40),
number = c(1, 0, 0, 0, 2, 2, 0 ,0, 3, 3, 3, 3, 3, 3, 3))打印为
id speed number
1 1 50 1
2 2 0 0
3 3 0 0
4 4 0 0
5 5 50 2
6 6 40 2
7 7 0 0
8 8 0 0
9 9 25 3
10 10 30 3
11 11 50 3
12 12 0 3** <- here is the difference
13 13 30 3
14 14 50 3
15 15 40 3我的数据中有100多万行,所以我希望这个解决方案在速度上是可以接受的。
设定"k“门槛的原因是,一些司机即使锁上汽车睡觉,也只会打开GPS。但在另一种情况下,当间隔小于k时,他们只是因为十字路口的灯光而停了下来。我想把注意力集中在长时间的止损上,而忽略短时的止损。
希望我的问题对you.Thank你有意义。
发布于 2017-08-07 00:16:33
由于处理速度是对超过1M行的生产数据集的关注,我建议使用data.table。
很容易识别后续非零条目的组:
library(data.table)
setDT(sample)[, number := rleid(speed > 0 ) * (speed > 0)][]id speed number 1: 1 50 1 2: 2 0 0 3: 3 0 0 4: 4 30 3 5: 5 50 3 6: 6 40 3 7: 7 0 0 8: 8 0 0 9: 9 25 5 10: 10 30 5 11: 11 50 5 12: 12 0 0 13: 13 30 7 14: 14 50 7 15: 15 40 7
组号不同,但没有连续编号。如果这是一个要求,它将变得棘手:
setDT(sample)[, number := as.integer(factor(rleid(speed > 0 ) * (speed > 0), exclude = 0))][]id speed number 1: 1 50 1 2: 2 0 NA 3: 3 0 NA 4: 4 30 2 5: 5 50 2 6: 6 40 2 7: 7 0 NA 8: 8 0 NA 9: 9 25 3 10: 10 30 3 11: 11 50 3 12: 12 0 NA 13: 13 30 4 14: 14 50 4 15: 15 40 4
如果确实需要,则可以将NAs替换为0
setDT(sample)[, number := as.integer(factor(rleid(speed > 0 ) * (speed > 0), exclude = 0))][
is.na(number), number := 0][]有另一种方法
setDT(sample)[, number := {
tmp <- speed > 0
cumsum(tmp - shift(tmp, fill = 0, type = "lag") > 0) * tmp
}][]id speed number 1: 1 50 1 2: 2 0 0 3: 3 0 0 4: 4 30 2 5: 5 50 2 6: 6 40 2 7: 7 0 0 8: 8 0 0 9: 9 25 3 10: 10 30 3 11: 11 50 3 12: 12 0 0 13: 13 30 4 14: 14 50 4 15: 15 40 4
https://stackoverflow.com/questions/45537141
复制相似问题