首页 > 解决方案 > 使用以 R 中的第一个条件为条件的条件进行过滤

问题描述

我想根据两个条件过滤行:

(1) 该行在某些指标列中被标记为“包含”,并且

(2) 该行位于第一个标准要包括的列之后的一分钟内。

我可以在循环中使用标准过滤方法来解决这个问题,但是有更复杂的解决方案吗?我很想看看人们能想出什么。

这是一个玩具数据集和基于问题描述的预期结果:

library(tidyverse)

df <- tibble(
time = c(0, 0.46, 0.73, 1.25, 1.58, 2.23, 2.65, 3.18, 3.45, 3.73, 4.26, 4.6, 4.66, 5.25, 5.78, 5.89, 6.51, 6.71, 6.97, 7, 7.95, 8.52, 8.93, 9.19, 9.28, 10.15, 10.75, 11.67, 11.88),
ind = c('include', 'exclude', 'exclude', 'exclude', 'exclude', 'include', 'include', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'include', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'exclude', 'include', 'exclude', 'exclude', 'exclude'))

df_des <- tibble(
time = c(0, 0.46, 0.73, 2.23, 2.65, 3.18, 3.45, 5.78, 5.89, 6.51, 6.71, 10.15, 10.75),
ind = c('include', 'exclude', 'exclude', 'include', 'include', 'exclude', 'exclude', 'include', 'exclude', 'exclude', 'exclude', 'include', 'exclude'))

这是我目前的解决方案:

df_tst <- list()
for(i in 1:nrow(df)){
  row_i <- slice(df, i)
  if(row_i$ind == "exclude"){
    next
  }else{
    df_tst[[i]] <- filter(df, time >= row_i$time, time <= row_i$time + 1)
  }
}
df_tst <- bind_rows(df_tst) %>%
  distinct(., time, ind) %>%
  arrange(., time)

其中df_tst产生与 中所需结果相同的答案df_des

标签: rdplyrfiltering

解决方案


这是一个dplyr解决方案,它在每次出现 时将数据分成组"include",然后在这些组中过滤:

df %>%
    # Associate each row with the most recent "include"
    mutate(group = cumsum(ind == "include")) %>%
    group_by(group) %>%
    filter(time <= (first(time) + 1))

输出(group左列展示它是如何工作的,但可以删除):

# A tibble: 13 x 3
# Groups:   group [5]
    time ind     group
   <dbl> <chr>   <int>
 1  0    include     1
 2  0.46 exclude     1
 3  0.73 exclude     1
 4  2.23 include     2
 5  2.65 include     3
 6  3.18 exclude     3
 7  3.45 exclude     3
 8  5.78 include     4
 9  5.89 exclude     4
10  6.51 exclude     4
11  6.71 exclude     4
12 10.2  include     5
13 10.8  exclude     5

推荐阅读