首次出现一定数量后对行进行求和

时间:2017-09-22 23:27:35

标签: r dplyr

我想在第一次出现一定数量后得到行的总和。在这种情况下,它是'10'

我虽然如果我们可以知道第一次出现后的行号和该组的结束行号,我们可以在它们之间求和。

我可以在每组中第一次出现'10',但我不知道如何得到行的总和。

df <- data.frame(gr=rep(c(1,2),c(7,9)), 
                 y_value=c(c(0,0,10,8,8,6,0),c(0,0,10,10,5,4,2,0,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       0
    9   2       0
    10  2      10
    11  2      10
    12  2       5
    13  2       4
    14  2       2
    15  2       0
    16  2       0

我的初步尝试是在下面,由于某种原因,即使对于分组部分也不起作用:(!

library(dplyr)
df%>%
  group_by(gr)%>%
  mutate(check1=any(y_value==10),row_sum=which(y_value == 10)[1])

预期输出

> df
           gr y_value sum_rows_range
        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       0      21/6
        9   2       0      21/6
        10  2      10      21/6
        11  2      10      21/6
        12  2       5      21/6
        13  2       4      21/6 
        14  2       2      21/6
        15  2       0      21/6
        16  2       0      21/6

2 个答案:

答案 0 :(得分:2)

这有点令人费解,我不是肯定的,这是你正在寻找的东西,但它确实符合你的输出。

  df %>% 
    group_by(gr) %>% 
    mutate(is_ten = cumsum(y_value == 10)) %>% 
    filter(is_ten > 0) %>% 
    filter(!(y_value == 10 & is_ten == 1)) %>% 
    group_by(gr) %>% 
    summarize(sum_rows_range = paste(sum(y_value), n(), sep = "/")) %>% 
    right_join(df)

# A tibble: 16 x 3
      gr sum_rows_range y_value
   <dbl>          <chr>   <dbl>
 1     1           22/4       0
 2     1           22/4       0
 3     1           22/4      10
 4     1           22/4       8
 5     1           22/4       8
 6     1           22/4       6
 7     1           22/4       0
 8     2           21/6       0
 9     2           21/6       0
10     2           21/6      10
11     2           21/6      10
12     2           21/6       5
13     2           21/6       4
14     2           21/6       2
15     2           21/6       0
16     2           21/6       0

答案 1 :(得分:2)

dplyr解决方案:

library(dplyr)
df %>%
  group_by(gr) %>%
  slice(if(any(y_value == 10)) (which.max(y_value == 10)+1):n() else row_number()) %>%
  summarize(sum = sum(y_value),
            rows = n()) %>%
  inner_join(df)

备注:

主要思想是在前10个发生后对行sliceany(y_value == 10))else row_number()仅用于处理y_value中没有10个案例的情况。

阅读?which.max的文档,您会注意到它应用于逻辑向量时,在本例中为y_value == 10,&#34;同时包含FALSE和{{1 }},TRUEwhich.min(x)分别返回第一个which.max(x)FALSE的索引,为TRUE。&#34;

换句话说,FALSE < TRUE将给出第一次出现的索引10.通过向其添加1,我可以在第一次出现10之后立即从值开始which.max(y_value == 10)。 / p>

<强>结果:

slice