【问题标题】:Subset dataframe based on previous accepted row基于先前接受的行的子集数据框
【发布时间】:2018-08-16 05:52:32
【问题描述】:

您好,我有一个如下的数据框,我希望能够对数据框进行子集化,因此只剩下结果数据框中的数据框。我想要 3 条规则

  1. 如果 startT 在前面的行 StartT 之后和前面的行 EndT 之前,则删除该行
  2. 如果 StartT 在前面的行 startT 和 EndT 之间,但即使该 EndT 在前面的行 EndT 之后,它仍然被删除
  3. 如果 startT 在前一行 StartT 和 EndT 之后,但在前一行 EndT 的 10 之内,则将其删除。

它还需要始终引用保存在数据框中的最后一行。

 StarT    EndT  Alarmcode 
1 3297.58 3298.62  13902 
2 3297.60 3346.20  13907 
3 3297.62 3346.17  14111 
4 3297.78 3346.13  13909 
5 3298.65 3346.08  13908 
6 3298.70 3298.75  13902 
7 3298.83 3298.88  13902 
8 3298.97 3298.98  13902 
9 3298.98 3346.03  13900 
10 3299.07 3346.00 13902 
11 3344.07 3352.75  1001 
12 3344.48 3345.90 13906 
13 3345.47 3345.87 15111 
14 3345.87 3347.78 15111 
15 3345.92 3346.58 13906 
16 3346.12 3346.17 13902 
17 3346.23 3346.50 13908 
18 3346.25 3346.30 13902 
19 3346.27 3347.75 14111 
20 3346.38 3346.43 13902 
21 3346.52 3346.53 13902 
22 3346.53 3347.70 13900 
23 3346.58 3347.67 13908 
24 3346.60 3347.63 13906 
25 3346.62 3347.60 13902 
26 3347.65 3352.30 13906 
27 3347.70 3347.72 13902 
28 3347.80 3352.25 13908 
29 3347.80 3352.27 15111 
30 3347.80 3352.28 14111 
31 3347.80 3347.85 13902 
32 3347.93 3347.98 13902 
33 3348.07 3348.12 13902 
34 3348.20 3348.22 13902 
35 3348.22 3352.23 13900 
36 3348.30 3352.00 13902 
37 3349.27 3352.22  13907 
38 14157.28 14157.28 5122 
39 27311.37 27311.38 5122 

应该留下这个:

       StarT EndT  Alarmcode 
1 3297.58 3298.62  13902 
38 14157.28 14157.28 5122 
39 27311.37 27311.38 5122 

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用来自dplyrlaglead 函数执行上述操作。 我不太了解您的规则...但我会尽力为您提供一般概念,以便您可以按照您对代码的理解来适应您的规则。

    本质上,使用lag 可以参考上一行。然后,您可以使用您的规则使用>< 创建逻辑语句。

    然后您可以使用filter 函数直接删除那些不符合条件的行。请注意,这将更改行的顺序,因为它们在继续下一条规则之前已被删除。要解决此问题,您可以使用mutate 创建一个检查规则状态的列,并且仅在规则逻辑的末尾应用filter

    下面是它的工作原理:

    如果 startT 在前面的行 StartT 之后和前面的行 EndT 之前,则删除该行

    df <- df %>%
      mutate(rule = ifelse(StarT > lag(StarT, 1) & StarT < lag(EndT, 1), 'remove', 'keep'))
    

    如果 StartT 在前面的行 startT 和 EndT 之间,但即使该 EndT 在前面的行 EndT 之后,它仍然被删除

    我不明白这个,对不起。听起来和第一个一样吗?

    如果 startT 在前一行 StartT 和 EndT 之后,但在前一行 EndT 的 10 之内,则将其删除。

    df <- df %>%
      mutate(rule = ifelse(StarT > lag(EndT, 1) + 10, 'remove', rule))
    

    那么最后你可以去:

    df <- df %>%
    filter(rule != 'remove') %>%  # this filters out any rows that fit remove rules above
    select(-rule) ## this remove the rule column
    

    希望这会有所帮助。 否则,如果您能阐明您的第二条规则,很乐意编写完整的代码。

    【讨论】:

    • 第二个你不明白,所以如果一个警报从 100 分钟开始并在 110 分钟结束,而下一个警报从 105 开始但在 115 结束(在上一个警报的时间内开始但在之后结束)我想也将其删除。
    • 第一条规则没有涵盖吗?您的第一条规则说明如果开始时间在前一个开始和结束之间,则将其删除。
    猜你喜欢
    • 2017-10-08
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多