首页 文章

基于条件分组对行进行求和

提问于
浏览
3

以前我asked与这个问题有关但我需要更优雅和一般的方法来解决这个问题 . 我有数据分组,我想根据条件求和范围内的一些行 . 我更喜欢使用'dplyr'这样做,因为我更直接地理解 .

我需要的条件如下;

1:对于第1组;找到'10'的第一个匹配项,并将此次出现的行 after 求和到该组的末尾并计算行数 .

2:对于第2组; 'find the last occurrence of ' 10'并将行 before 这一事件的总和汇总到组的开头并计算行数!

3:对于第3组;找到'10'的第一个匹配项,并将此事件的行 before 求和到该组的起始行并计算行数 .

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


> df
   gr y_value
1   1       0
2   1       0
3   1      10
4   1       8
5   1       8
6   1       6
7   1       0
8   2      10
9   2      10
10  2      10
11  2       8
12  2       7
13  2       6
14  2       2
15  2       0
16  2       0
17  3       8
18  3       5
19  3       8
20  3       7
21  3       6
22  3       2
23  3      10
24  3      10
25  3       8
26  3       7
27  3       0

它猜这样的东西应该工作,但无法弄清楚如何实现这个 dplyr

count <- function(y,gr){
    if (any(y==10)&(gr==1)) {
     *
     *
     *
if (any(y==10)&(gr==2)) 
 *
 *
 *
 *

}}

df%>%
library(dplyr)

  df %>%
  group_by(gr) %>%
  do(data.frame(.,count_rows=count(y_value,gr)))

预期产出

> df
    gr y_value sum nrow
1   1       0  22   4
2   1       0  22   4
3   1      10  22   4
4   1       8  22   4
5   1       8  22   4
6   1       6  22   4
7   1       0  22   4
8   2      10  23   6
9   2      10  23   6
10  2      10  23   6
11  2       8  23   6
12  2       7  23   6
13  2       6  23   6
14  2       2  23   6
15  2       0  23   6
16  2       0  23   6
17  3       8  28   6
18  3       5  28   6
19  3       7  28   6
20  3       6  28   6
21  3       2  28   6
22  3      10  28   6
23  3      10  28   6
24  3       8  28   6
25  3       7  28   6
26  3       0  28   6

2 回答

  • 1

    希望这可以帮助!

    Edit note: OP修改后的代码更新了他的原始要求)

    #sample data - I slightly changed sample data (replaced 0 by 10 in 2nd row) for group 1 to satisfy your condition
    df <- data.frame(gr=rep(c(1,2,3),c(7,9,11)), 
                     y_value=c(c(0,10,10,8,8,6,0),c(10,10,10,8,7,6,2,0,0), c(8,5,8,7,6,2,10,10,8,7,0)))
    
    library(dplyr)
    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))) %>% 
      mutate(nrow=n(), sum=sum(y_value)) %>%
      select(gr,sum,nrow) %>%
      distinct()
    
    #final output
    df<- left_join(df,df_temp, by='gr')
    
  • 2

    我想你是在 cummax 之后:

    df %>%
      group_by(gr) %>%
      mutate(in_scope = if_else(gr == 1,
                                cummax(lag(y_value == 10, default = FALSE)),
                                if_else(gr == 2,
                                        cummax(lag(y_value == 10, default = FALSE) & y_value != 10),
                                        1L - cummax(y_value == 10)))) %>%
      ungroup %>%
      group_by(gr) %>%
      summarise(the_sum = sum(y_value * in_scope),
                the_count = sum(in_scope))
    
    
    # A tibble: 3 x 3
         gr the_sum the_count
      <dbl>   <dbl>     <int>
    1     1      22         4
    2     2      23         6
    3     3      36         6
    

相关问题