在R中,我希望在基于变量 x 的运行对数据进行分组之后对其进行汇总(也就是说,每组数据对应于连续 x 值相同的数据的子集) . 例如,考虑以下数据框,我想在 x 的每次运行中计算平均 y 值:
(dat
# x y
# 1 1 1
# 2 1 2
# 3 1 3
# 4 2 4
# 5 2 5
# 6 1 6
# 7 2 7
在此示例中, x 变量的运行长度为3,然后是2,然后是1,最后是1,在这四次运行中取值1,2,1和2 . 这些组中相应的 y 均为2,4.5,6和7 .
使用 tapply 在基础R中执行此分组操作很容易,传递 dat$y 作为数据,使用 rle 计算 dat$x 的运行编号,并传递所需的汇总函数:
tapply(dat$y, with(rle(dat$x), rep(seq_along(lengths), lengths)), mean)
# 1 2 3 4
# 2.0 4.5 6.0 7.0
我想我可以直接将这个逻辑转移到dplyr,但到目前为止我的尝试都以错误结束了:
library(dplyr)
# First attempt
dat %>%
group_by(with(rle(x), rep(seq_along(lengths), lengths))) %>%
summarize(mean(y))
# Error: cannot coerce type 'closure' to vector of type 'integer'
# Attempt 2 -- maybe "with" is the problem?
dat %>%
group_by(rep(seq_along(rle(x)$lengths), rle(x)$lengths)) %>%
summarize(mean(y))
# Error: invalid subscript type 'closure'
为了完整性,我可以使用 cumsum , head 和 tail 来重新实现 rle 运行ID来解决这个问题,但这会使分组代码更难以阅读并涉及到一些重新发明轮子:
dat %>%
group_by(run=cumsum(c(1, head(x, -1) != tail(x, -1)))) %>%
summarize(mean(y))
# run mean(y)
# (dbl) (dbl)
# 1 1 2.0
# 2 2 4.5
# 3 3 6.0
# 4 4 7.0
是什么导致我的基于_1825158的分组代码在 dplyr 中失败,是否有任何解决方案使我能够在按运行ID分组时继续使用 rle ?