В 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
идентификатор запуска, используя 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
в dplyr
, и есть ли какое-либо решение, которое позволяет мне продолжать использовать rle
при группировке по идентификатору выполнения?