在 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
, and 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
基于失败的分组代码dplyr
,有什么解决方案可以让我继续使用rle
当按运行 ID 分组时?
Update:截至 2023 年,这似乎已由 dplyr 包修复,这样我的原始代码就可以正常工作,并且不需要任何解决方法。