使用dplyr按组计算每个块?

calculate each chunk by group using dplyr?

如何使用 dplyr 包获得预期的计算?

row value   group   expected
1   2       1       =NA
2   4       1       =4-2
3   5       1       =5-4
4   6       2       =NA
5   11      2       =11-6
6   12      1       =NA
7   15      1       =15-12

我试过了

df=read.table(header=1, text='    row    value  group
1   2   1
2   4   1
3   5   1
4   6   2
5   11  2
6   12  1
7   15  1')

df %>% group_by(group) %>% mutate(expected=value-lag(value))

虽然第 1-3 行和第 6-7 行被标记为相同的组编号,但我如何计算每个块(第 1-3、4-5、6-7 行)?

由于您的 group 变量对此没有用,创建一个新变量 aux 并将其用作分组变量:

library(dplyr)
df$aux <- rep(seq_along(rle(df$group)$values), times = rle(df$group)$lengths)

df %>% group_by(aux) %>% mutate(expected = value - lag(value))

Source: local data frame [7 x 5]
Groups: aux

  row value group aux expected
1   1     2     1   1       NA
2   2     4     1   1        2
3   3     5     1   1        1
4   4     6     2   2       NA
5   5    11     2   2        5
6   6    12     1   3       NA
7   7    15     1   3        3

这是一个类似的方法。我使用 cumsum 创建了一个新的组变量。每当 group 中的两个数之差不为 0 时,R 分配一个新的组号。如果您有更多数据,此方法可能会有所帮助。

library(dplyr)

mutate(df, foo = cumsum(c(T, diff(group) != 0))) %>%
group_by(foo) %>%
mutate(out = value - lag(value))

#  row value group foo out
#1   1     2     1   1  NA
#2   2     4     1   1   2
#3   3     5     1   1   1
#4   4     6     2   2  NA
#5   5    11     2   2   5
#6   6    12     1   3  NA
#7   7    15     1   3   3

这是一个使用 data.table_1.9.5 的选项。 devel 版本引入了新函数 rleidshift(默认 type 是 "lag",fill 是 "NA"),可以用于此。

library(data.table)
setDT(df)[, expected:=value-shift(value) ,by = rleid(group)][]
#     row value group expected
#1:   1     2     1       NA
#2:   2     4     1        2
#3:   3     5     1        1
#4:   4     6     2       NA
#5:   5    11     2        5
#6:   6    12     1       NA
#7:   7    15     1        3