r 数据框中的组的总和,不包括第一个值

cumsum of groups in r dataframe excluding the first value

我有一个数据框,其中包含由因子值定义的组。我正在尝试添加一个包含基于每个单独组的累计总和的列。

bbb<-c(2,4,6,3,5,7)
factor<-gl(2,3)
df<-data.frame(bbb,factor)

我找到了 ave() 函数并成功使用了它,就像这样:

df$cumbbb<-ave(df$bbb,df$factor,FUN=cumsum)

不过我现在需要更改一个相对较小的东西。我想忽略累计总和中每组的第一个值。

## At the moment the output is
[1]  2  6 12  3  8 15
## The output I need is
[1] 0 4 10  0 5 12

到目前为止我的想法是:

在 ave() 中找到一些额外的功能,例如,在适当的地方插入 [2:length],这是我目前还没有做到的。

像我一样执行ave()函数,然后从该组的所有累积和值中减去每个组的第一个bbb。问题在于,我不知道如何根据该因素确定每个组的第一个值。

或者我假设使用 split/tapply 或其他一些应用函数可以更专业地完成它。

这实际上让我想到了一个额外的问题:除了例如?ave?它没有提到我可以使用它的功能以及我可以使用 FUN=cumsum 的事实我只知道感谢这个论坛。或者这应该是常识,因为它在帮助页面上提到了 'function' 一词?除了 youtube 教程之外,我也无法找到有关软件包的综合信息。例如,我假设 dyplr 也会对我的问题有某种优雅的解决方案。我只是不知道如何去做。谢谢!

我们可以删除第一个元素,得到其余的cumsum并在ave

FUN中与0连接
with(df, ave(bbb, factor, FUN = function(x) c(0, cumsum(x[-1]))))
#[1]  0  4 10  0  5 12

有了dplyr,我们可以使用与上面相同的连接逻辑

library(dplyr)
df %>% 
   group_by(factor) %>% 
   mutate(cumbbb = c(0, cumsum(bbb[-1])))

或者用row_number()创建一个逻辑索引,乘以'bbb'得到第一个值0(因为FALSE是0而TRUE是1)在做之前cumsum

df %>%
    group_by(factor) %>% 
    mutate(cumbbb = cumsum((row_number() > 1) * bbb))
# A tibble: 6 x 3
# Groups: factor [2]
#    bbb factor cumbbb
#  <dbl> <fctr>  <dbl>
#1  2.00 1        0   
#2  4.00 1        4.00
#3  6.00 1       10.0 
#4  3.00 2        0   
#5  5.00 2        5.00
#6  7.00 2       12.0 

使用 dplyr

的替代解决方案
bbb<-c(2,4,6,3,5,7)
factor<-gl(2,3)
df<-data.frame(bbb,factor)

library(dplyr)

df %>%
  group_by(factor) %>%                                        # for each factor value
  mutate(cs = cumsum(ifelse(row_number() == 1, 0, bbb))) %>%  # replace bbb value in position 1 with 0 and get cumsum
  ungroup()                                                   # forget the grouping

# # A tibble: 6 x 3
#     bbb factor    cs
#   <dbl> <fct>  <dbl>
# 1    2. 1         0.
# 2    4. 1         4.
# 3    6. 1        10.
# 4    3. 2         0.
# 5    5. 2         5.
# 6    7. 2        12.