【问题标题】:Filter row by first and last condition in R按R中的第一个和最后一个条件过滤行
【发布时间】:2021-11-27 15:09:40
【问题描述】:

我想删除特定因素之前的所有行(在这种情况下是第一个 Running in Run 列)和最后一个特定情况之后的所有行(在这种情况下也是 Running in Run 列)。

数据

Date Time Run
17/04/12 00:10:00
17/04/12 00:19:00
17/04/12 00:25:00 Running
17/04/12 00:29:00 Running
17/04/12 00:25:00 Stop
17/04/12 00:29:00 Running
17/04/12 00:30:00 Running
18/04/12 00:10:00 Stop
18/04/12 00:14:00 Running
18/04/12 00:20:00 Stop
18/04/12 00:24:00 Stop
18/04/12 00:26:00 Stop

结果:

Date Time Run
17/04/12 00:25:00 Running
17/04/12 00:29:00 Running
17/04/12 00:25:00 Stop
17/04/12 00:29:00 Running
17/04/12 00:30:00 Running
18/04/12 00:10:00 Stop
18/04/12 00:14:00 Running

【问题讨论】:

  • 请您使用dput 与我们分享一个示例数据集
  • 是的。这里:图书馆(tidyverse);数据

标签: r dataframe filter rows


【解决方案1】:

这是使用dplyr的解决方案

library(dplyr)

df %>% 
  filter(Run %in% c("Running", "Stop")) %>% 
  slice(1:max(which(Run == "Running")))

这给了我们:

# A tibble: 7 x 3
  Date     Time     Run    
  <chr>    <chr>    <chr>  
1 17/04/12 00:25:00 Running
2 17/04/12 00:29:00 Running
3 17/04/12 00:25:00 Stop   
4 17/04/12 00:29:00 Running
5 17/04/12 00:30:00 Running
6 18/04/12 00:10:00 Stop   
7 18/04/12 00:14:00 Running

【讨论】:

    【解决方案2】:

    在您的数据分析过程中,您会经常遇到这个问题。 如果您想要或将不得不添加更多逻辑检查,您可以引入您过滤的变量。在您的情况下,我们可以简单地计算 Running 和 Stop 的出现次数。然后,我们使用额外的列来过滤您的数据框。

    library(dplyr)
    
    data %>% 
     mutate(  RunCounts = cumsum(Run == "Running")
           , StopCounts = cumsum(Run == "Stop")
           ) %>% 
     filter(RunCounts >= 1 & StopCounts < max(StopCounts))
    

    这会产生:

    # A tibble: 7 x 5
      Date     Time     Run     RunCounts StopCounts
      <chr>    <chr>    <chr>       <int>      <int>
    1 17/04/12 00:25:00 Running         1          2
    2 17/04/12 00:29:00 Running         2          2
    3 17/04/12 00:25:00 Stop            2          3
    4 17/04/12 00:29:00 Running         3          3
    5 17/04/12 00:30:00 Running         4          3
    6 18/04/12 00:10:00 Stop            4          4
    7 18/04/12 00:14:00 Running         5          4
    

    您可以通过选择您感兴趣的列来删除引入的列:

    data %>% mutate(RunCounts = cumsum(Run == "Running"), StopCounts = cumsum(Run == "Stop")) %>% filter(RunCounts >= 1 & StopCounts < max(StopCounts)) %>% select(Date, Time, Run)
    # A tibble: 7 x 3
      Date     Time     Run    
      <chr>    <chr>    <chr>  
    1 17/04/12 00:25:00 Running
    2 17/04/12 00:29:00 Running
    3 17/04/12 00:25:00 Stop   
    4 17/04/12 00:29:00 Running
    5 17/04/12 00:30:00 Running
    6 18/04/12 00:10:00 Stop   
    7 18/04/12 00:14:00 Running
    

    【讨论】:

    • 不错。但是在这个例子中,如果在最后一次运行之后有很多停止,使用你的脚本,就不可能删除额外的停止。我编辑了示例。
    • 您可以构造许多复杂的逻辑条件。显然,这取决于您手头的数据集和问题案例。所以你要找的是一个条件:max StopCounts and previous Run == "Running"。您可以使用lead()/lag() 在 dplyr 中查找上一个/下一个。如果您需要组合多个甚至可能更复杂的逻辑条件,case_when() 是您的朋友。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    相关资源
    最近更新 更多