【问题标题】:Filtering and summing rows in dplyr在 dplyr 中过滤和求和行
【发布时间】:2018-04-20 11:34:19
【问题描述】:

我有一个数据,我想先过滤一些行并对剩余的行求和。

过滤条件如下;

  1. 对于 gr==1,找到最后一次出现的 y_value==10 并保留它之前的所有行(包括该值最后一次出现的 10 行)!
  2. 对于 gr==2,找到 y_value==10 的第一次出现并保留其后的所有行(包括该值第一次出现的 10 行)!

数据是这样的;

df <- data.frame(gr=rep(c(1,2),c(8,7)), 
                 y_value=c(c(2,10,10,8,10,6,0,0),c(0,0,10,10,6,8,10)))



    gr y_value
1   1       2
2   1      10
3   1      10
4   1       8
5   1      10
6   1       6
7   1       0
8   1       0
9   2       0
10  2       0
11  2      10
12  2      10
13  2       6
14  2       8
15  2      10

我根据summing-rows-based-on-conditional-in-groups尝试了这个;

df_temp <- df %>% 
  group_by(gr) %>% 
  mutate(rows_to_aggregate=cumsum(y_value==10)) %>% 
  filter(ifelse(gr==1, rows_to_aggregate !=0, ifelse(gr==2, rows_to_aggregate ==0 | y_value==10, rows_to_aggregate ==0))) %>% 
  filter(ifelse(gr==1, row_number(gr) != 1, ifelse(gr==2, row_number(gr) != n(), rows_to_aggregate ==0)))

但是如果我在gr==1 中执行rows_to_aggregate !=0,感兴趣的行将会消失!在这一点上的任何指南将不胜感激!

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    df_to_aggregate <- df %>% 
        group_by(gr) %>% 
        mutate(rows_to_aggregate = cumsum(y_value == 10)) %>% 
        filter(!(gr == 1 & rows_to_aggregate == max(rows_to_aggregate) & y_value != 10)) %>%
        filter(!(gr == 2 & rows_to_aggregate == 0)) %>%
        select(-rows_to_aggregate)
    df_to_aggregate
    
    # A tibble: 10 x 2
    # Groups:   gr [2]
         gr y_value
      <dbl>   <dbl>
    1     1       2
    2     1      10
    3     1      10
    4     1       8
    5     1      10
    6     2      10
    7     2      10
    8     2       6
    9     2       8
    10    2      10
    

    【讨论】:

    • 感谢您的聪明回答,OTH 我想在8 之后保留10gr==1 中。这是主要的瓶颈:((我还更新了 OP。很抱歉我应该提到这一点!
    • @Alexander 我明白了。稍微改变一下过滤条件应该可以。更新了我的答案。
    • 非常感谢。你的算法很棒!
    【解决方案2】:

    不知道如何在 dplyr 中执行,但是这段代码似乎可以工作

    gr1 = df[df$gr==1,]
    last = tail(which(gr1$y_value==10),1)
    gr1 = gr1[1:(last-1),]
    gr2 = df[df$gr==2,]
    first = head(which(gr2$y_value==10),1)
    gr2 = gr2[(first+1):dim(gr2)[1],]
    final = rbind(gr1,gr2)
    

    【讨论】:

    • 谢谢。如果可能的话,希望在 dplyr 中有解决方案;)
    【解决方案3】:

    您可以为每个gr 使用不同的切片条件slice

    df %>% 
      group_by(gr) %>% 
      slice(if(any(gr==1)) {1:max(which(y_value==10))} else {min(which(y_value==10)):n()}) 
    
          gr y_value
     1     1       2
     2     1      10
     3     1      10
     4     1       8
     5     1      10
     6     2      10
     7     2      10
     8     2       6
     9     2       8
    10     2      10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      • 2021-10-25
      相关资源
      最近更新 更多