在 R 中,我想在根据变量的运行对其进行分组后总结我的数据x
(也就是每组数据对应于连续x
值相同的数据子集)。例如,考虑以下数据框,我想在其中计算y
每次运行的平均值x
:
(dat <- data.frame(x=c(1, 1, 1, 2, 2, 1, 2), y=1:7))
# 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。
在基础 R 中使用 、作为数据tapply
传递、使用从 计算运行次数并传递所需的汇总函数很容易执行此分组操作: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'
为了完整起见,我可以自己使用,和来重新实现rle
运行 id来解决这个问题,但它使分组代码更难阅读,并且涉及到一些重新发明轮子:cumsum
head
tail
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
是什么导致我rle
的 -based 分组代码失败,是否有任何解决方案可以让我在按运行 id 分组时dplyr
继续使用?rle