计算R中数据框中条件为1和0的列的行总和,想要连续1与0之间的和

时间:2019-12-15 22:34:32

标签: r sum aggregate subset subset-sum

可重复输入数据帧的示例:

onoff = c(0,1,1,1,0,0,1,1,1,0)
amount = c(0,0.5,0,0.6,0,0,0.5,0.6,0.7,0)

mockdata = data.frame(onoff, amount)

看起来像这样。

picture of dataframe

我想对onoff在0到1之间的行序列求和。 因此,在此示例中,我将获得两组总和,第一组在2和4行之间,第二组在7和9行之间。 因此,我将输出两个数字,即1.1和1.8。

不确定如何执行此操作,将不胜感激!

3 个答案:

答案 0 :(得分:3)

我们可以使用rleid中的data.table创建一个分组列,然后使用它来获得sum

library(dplyr)
library(data.table)
mockdata %>% 
   group_by(grp = rleid(onoff)) %>% 
   mutate(Sum = sum(amount) * onoff)
# A tibble: 10 x 4
# Groups:   grp [5]
#   onoff amount   grp   Sum
#   <dbl>  <dbl> <int> <dbl>
# 1     0    0       1   0  
# 2     1    0.5     2   1.1
# 3     1    0       2   1.1
# 4     1    0.6     2   1.1
# 5     0    0       3   0  
# 6     0    0       3   0  
# 7     1    0.5     4   1.8
# 8     1    0.6     4   1.8
# 9     1    0.7     4   1.8
#10     0    0       5   0  

如果我们需要汇总的输出

mockdata %>% 
  group_by(grp = rleid(onoff)) %>% 
  filter(onoff == 1) %>% 
  summarise(amount = sum(amount))

答案 1 :(得分:1)

aggregate(mockdata$amount, list(grp = c(1, cumsum(diff(mockdata$onoff) == 1))), sum)

      grp   x
1       1 1.1
2       2 1.8

答案 2 :(得分:0)

使用基数R,我们可以使用rle创建组,并使用tapply计算汇总数据

with(rle(mockdata$onoff != 1), tapply(mockdata$amount, 
           rep(cumsum(values), lengths), sum))

#  1   2   3 
#1.1 1.8 0.0 

或者我认为更接近预期输出的另一种方法是使用onoff = 1

过滤行
mockdata$row <- seq_len(nrow(mockdata))
temp <- subset(mockdata, onoff == 1)
tapply(temp$amount, cumsum(c(TRUE, diff(temp$row) > 1)), sum)

#  1   2 
#1.1 1.8