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