连续相同值的总和

时间:2018-04-25 14:45:11

标签: r

    slope   term
     0.5    1
     0.8    1
     0.3    0
    0.25    0
    0.18    0
     0.4    0
     1.2    1
     3.6    1
     0.67   1
     0.3    0
     0.8    1
     0.4    0

我想知道每个事件的斜率之和,其中1和如果可用连续1发生。所以我得到这样的输出:

slope   term    sum_slope
0.5      1        1.3
0.8      1        1.3
0.3      0        NA
0.25     0        NA
0.18     0        NA
0.4      0        NA
1.2      1       5.47
3.6      1       5.47
0.67     1       5.47
0.3      0        NA
0.8      1       0.8
0.2      0        NA

3 个答案:

答案 0 :(得分:1)

它不是完全您想要的,但您可以使用data.table::rleid对数据进行分组 - rleidrle

数据

df <- read.table(text="slope   term
     0.5    1
     0.8    1
     0.3    0
    0.25    0
    0.18    0
     0.4    0
     1.2    1
     3.6    1
     0.67   1
     0.3    0
     0.8    1", header=TRUE)

解决方案

library(data.table)
dt <- setDT(df)
dt[, sum:=sum(slope)*max(term), by=rleid(term)]
dt

    # slope term  sum
 # 1:  0.50    1 1.30
 # 2:  0.80    1 1.30
 # 3:  0.30    0 0.00
 # 4:  0.25    0 0.00
 # 5:  0.18    0 0.00
 # 6:  0.40    0 0.00
 # 7:  1.20    1 5.47
 # 8:  3.60    1 5.47
 # 9:  0.67    1 5.47
# 10:  0.30    0 0.00
# 11:  0.80    1 0.80

答案 1 :(得分:1)

以下是使用base R的选项。使用rle('grp')创建分组变量,然后使用ave创建分组变量,按'grp'分组,在转换对应于''的'后,获取'{1}}'斜率'术语'0为sum

NA

答案 2 :(得分:1)

1)这使用rleid中的data.table创建分组变量,其余为基础R. ave计算每个组的总和以及0个组中的ifelse个NA。

library(data.table)
transform(DF, sum_slope = ave(slope, rleid(term), FUN = sum) * ifelse(term, 1, NA))

,并提供:

   slope term sum_slope
1   0.50    1      1.30
2   0.80    1      1.30
3   0.30    0        NA
4   0.25    0        NA
5   0.18    0        NA
6   0.40    0        NA
7   1.20    1      5.47
8   3.60    1      5.47
9   0.67    1      5.47
10  0.30    0        NA
11  0.80    1      0.80
12  0.40    0        NA

2)以上的这种变体仅使用基数R.它用基本表达式rleid替换cumsum(...),它也是相同的。

transform(DF, sum_slope = 
  ave(slope, cumsum(c(FALSE, diff(term) != 0)), FUN = sum) * ifelse(term, 1, NA))

注意

可重复输入的输入:

Lines <- "
 slope   term
     0.5    1
     0.8    1
     0.3    0
    0.25    0
    0.18    0
     0.4    0
     1.2    1
     3.6    1
     0.67   1
     0.3    0
     0.8    1
     0.4    0"
DF <- read.table(text = Lines, header = TRUE)