我有一个带有id,排序时间值和值的数据帧。对于每组id,我想删除值小于时间值较小的行的行。
data <- data.frame(id = c(rep(c("a", "b"), each = 3L), "b"),
time = c(0, 1, 2, 0, 1, 2, 3),
value = c(1, 1, 2, 3, 1, 2, 4))
> data
id time value
1 a 0 1
2 a 1 1
3 a 2 2
4 b 0 3
5 b 1 1
6 b 2 2
7 b 3 4
结果将是:
> data
id time value
1 a 0 1
2 a 2 2
3 b 0 3
4 b 3 4
(对于id == b
行,其中time %in% c(3, 4)
被删除,因为值value
小于time
更低的值
我在考虑lag
data %>%
group_by(id) %>%
filter(time == 0 | lag(value, order_by = time) < value)
Source: local data frame [5 x 3]
Groups: id [2]
id time value
<fctr> <dbl> <dbl>
1 a 0 1
2 a 2 2
3 b 0 3
4 b 2 2
5 b 3 4
但它没有按预期工作,因为它是一个矢量化函数,所以相反的想法是使用“递归滞后函数”或检查最后一个最大值。我可以通过循环递归地执行它,但我确信有更直接和更高级别的方法来执行它。
任何帮助将不胜感激,谢谢!
答案 0 :(得分:3)
以下是data.table
解决方案:
library(data.table)
setDT(data)
data[, myVal := cummax(c(0, shift(value)[-1])), by=id][value > myVal][, myVal := NULL][]
id time value
1: a 0 1
2: a 2 2
3: b 0 3
4: b 3 4
链的第一部分使用shift
和cummax
来创建滞后值变量的累积最大值。在c(0, shift(value)[-1])
中,添加0以提供比变量中任何值更值的值。更一般地说,您可以使用min(value)-1
[-1]
子集删除shift
的第一个元素,即NA。链的第二部分选择值大于累积最大值的观察值。最后两个链删除累积的最大变量并打印出结果。
答案 1 :(得分:3)
另一种选择是使用data.table
library(data.table) # v1.10.0
setDT(data)[!data, on = .(id, time > time, value <= value)]
# id time value
# 1: a 0 1
# 2: a 2 2
# 3: b 0 3
# 4: b 3 4
基本上说:&#34; 如果time
较大但value
不相等,那么我不想要这些行(!
签)&#34;
答案 2 :(得分:0)
以下是dplyr
的选项。按照&#39; id&#39;进行分组后,我们filter
行&#39;值&#39;大于“延迟”的累积最大值。的价值&#39;柱
library(dplyr)
data %>%
group_by(id) %>%
filter(value > cummax(lag(value, default = 0)) )
# id time value
# <fctr> <dbl> <dbl>
#1 a 0 1
#2 a 2 2
#3 b 0 3
#4 b 3 4
或slice
{id}后面的另一个选项是arrange
和&#39;时间&#39; (正如OP提到的order
data %>%
group_by(id) %>%
arrange(id, time) %>%
slice(which(value > cummax(lag(value, default = 0))))