使用dplyr按组计算每个块?

时间:2015-01-31 02:14:52

标签: r 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行)?

3 个答案:

答案 0 :(得分:3)

由于您的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

答案 1 :(得分: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

答案 2 :(得分:2)

以下是使用data.table_1.9.5的选项。 devel版本引入了新功能rleidshift(默认type是&#34;滞后&#34;而fill是&#34; NA&#34;)对此有用。

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