【问题标题】:R: filter rows based on a condition in one columnR:根据一列中的条件过滤行
【发布时间】:2021-06-25 12:29:18
【问题描述】:

我有一个数据框:

a<-c(1,1,1,1,1,1,1,1,1,1,1)
b<-c(100,100,100,100,100,100,100,100,100,100,100)
c<-c(1,3,1,1,3,1,1,3,1,1,3)
d<-c(3400,3403,3407,3408,3412,3423,3434,3436,3445,3454,3645)
df<-data.frame(d,b,c,a)
df
      d   b c a
1  3400 100 1 1
2  3403 100 3 1
3  3407 100 1 1
4  3408 100 1 1
5  3412 100 3 1
6  3423 100 1 1
7  3434 100 1 1
8  3436 100 3 1
9  3445 100 1 1
10 3454 100 1 1
11 3645 100 3 1

并且我想始终过滤一个满足以下条件的行对:第一行的 c 列值必须为 3,第二行的 c 列值必须为 1,并且该对之间的列 d 值具有

      d   b c a
2  3403 100 3 1
3  3407 100 1 1
8  3436 100 3 1
9  3445 100 1 1

我尝试了以下方法:

filter(df,first(c)==3,nth(c,2)==1,any(diff(d) < 10))

但由于某种原因,它不起作用。感谢您的帮助!

【问题讨论】:

    标签: r filter conditional-statements


    【解决方案1】:

    您可以先使用which 建立第一对零件的索引:

    library(dplyr)
    inds <- which(df$c == 3 & lead(df$c) == 1 & lead(df$d) - df$d < 10)
    

    然后在索引 plus 1:

    上子集您的数据框
    df[sort(unique(c(inds, inds + 1))),]
         d   b c a
    2 3403 100 3 1
    3 3407 100 1 1
    8 3436 100 3 1
    9 3445 100 1 1
    

    或者,您可以这样做:

    library(dplyr)
    df1 <- df %>%                                        # get the first row
      filter(c == 3 & lead(c) == 1 & lead(d) - d < 10) 
    df2 <- df %>%                                        # get the second row
      filter(lag(c) == 3 & c == 1 & d - lag(d) < 10)
    arrange(rbind(df1, df2), d)                          # bind the two together and arange by d
    

    【讨论】:

      【解决方案2】:

      以下代码并不简单,但它产生了预期的结果。

      library(dplyr)
      
      df %>%
        mutate(flag = cumsum(c == 3)) %>%
        group_by(flag) %>%
        slice_head(n = 2) %>%
        filter(n() > 1) %>%
        mutate(flag = flag*(diff(d) < 10)) %>%
        ungroup() %>%
        filter(flag > 0) %>%
        select(-flag)
      ## A tibble: 4 x 4
      #      d     b     c     a
      #  <dbl> <dbl> <dbl> <dbl>
      #1  3403   100     3     1
      #2  3407   100     1     1
      #3  3436   100     3     1
      #4  3445   100     1     1
      

      【讨论】:

        猜你喜欢
        • 2013-09-06
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        • 2022-09-29
        • 2016-11-13
        • 2018-09-15
        • 2021-01-04
        • 2018-08-07
        相关资源
        最近更新 更多