Я посмотрел, и я не понимаю, как это возможно с самой dplyr
.Однако мы можем взломать функцию group_by
, чтобы сделать ее кумулятивной.Я быстро проведу вас через это:
Во-первых, я делаю ваш df.Это не совсем соответствует вашему выводу, поэтому я немного изменил его.
df = data.frame(a = c(1,1,3,2,2), b=6:10)
df$b[3] <- 3
Теперь я использую обычный group_by
, чтобы проверить, что он на самом деле делает с data.frame
.
library(dplyr)
df_grouped <- df %>%
arrange(a) %>%
group_by(a)
> attributes(df_grouped)
$class
[1] "grouped_df" "tbl_df" "tbl" "data.frame"
$row.names
[1] 1 2 3 4 5
$names
[1] "a" "b"
$vars
[1] "a"
$drop
[1] TRUE
$indices
$indices[[1]]
[1] 0 1
$indices[[2]]
[1] 2 3
$indices[[3]]
[1] 4
$group_sizes
[1] 2 2 1
$biggest_group_size
[1] 2
$labels
a
1 1
2 2
3 3
Таким образом, помимо прочего, существует новый атрибут с именем indices
, на который ссылается группа каждого элемента в сгруппированной переменной.На самом деле мы можем просто изменить это, чтобы сделать его кумулятивным.
for (i in seq_along(attributes(df_grouped)[["indices"]])[-1]) {
attributes(df_grouped)[["indices"]][[i]] <- c(
attributes(df_grouped)[["indices"]][[i - 1]],
attributes(df_grouped)[["indices"]][[i]]
)
}
Это выглядит немного странно, но просто.Элементы каждой группы добавляются в следующую группу.Например, все элементы из группы 1 добавляются в группу 2.
> attributes(df_grouped)$indices
[[1]]
[1] 0 1
[[2]]
[1] 0 1 3 4
[[3]]
[1] 0 1 3 4 2
Мы можем использовать измененные группы обычным образом dplyr
.
> df_grouped %>%
+ summarise(sum_b = mean(b))
# A tibble: 3 x 2
a sum_b
<dbl> <dbl>
1 1 6.5
2 2 8
3 3 7
Теперь, конечно, это довольнонекрасиво и выглядит очень нахальноНо внутри функции, которая на самом деле не имеет значения, пока она все еще эффективна (что это такое).Итак, давайте сделаем пользовательский group_by
.
group_by_cuml <- function(.data, ...) {
.data_grouped <- group_by(.data, ...)
for (i in seq_along(attributes(.data_grouped)[["indices"]])[-1]) {
attributes(.data_grouped)[["indices"]][[i]] <- c(
attributes(.data_grouped)[["indices"]][[i - 1]],
attributes(.data_grouped)[["indices"]][[i]]
)
}
return(.data_grouped)
}
Теперь вы можете использовать пользовательскую функцию в чистой dplyr
трубе.
> df %>%
+ group_by_cuml(a) %>%
+ summarise(sum_b = mean(b))
# A tibble: 3 x 2
a sum_b
<dbl> <dbl>
1 1 6.5
2 2 8
3 3 7