У меня есть некоторые аккуратные данные, содержащие идентичные серии длин 'value', упорядоченные по 'idx', идентифицированные по 'id', категоризированные по 'type', с пустым столбцом результата 'rollAgg', помеченным тегом.
> head(df,15)
# A tibble: 15 x 5
id idx type value rollAgg
<int> <int> <chr> <dbl> <dbl>
1 1 1 A 4.50 0
2 1 2 A 2.47 0
3 1 3 A 2.78 0
4 1 4 A 2.29 0
5 1 5 A 1.48 0
6 1 6 A 2.30 0
7 1 7 A 4.94 0
8 1 8 A 4.68 0
9 1 9 A 3.36 0
10 1 10 A 4.27 0
11 2 1 B 4.10 0
12 2 2 B 1.25 0
13 2 3 B 3.95 0
14 2 4 B 2.78 0
15 2 5 B 2.28 0
...
Я хочу разделить данные по 'id', а затем использовать rollapply (), чтобы сгенерировать вектор либо скользящего среднего (значения), либо скользящей суммы (значения), определенного по типу.
Могу ли я присвоить результат вектора из rollapply () пустому столбцу rollAgg в данных split (), а затем unsplit ()? (вместо создания пустого вектора требуемого размера, а затем cbind ())
Я могу присвоить результат (ы) пустому вектору (или матрице)
## switchable mean/sum function
mean_sum <- function(x, b = TRUE){
if (b)
{
mean(x)
} else {
sum(x)
}
}
##
#dummy data
df <- tibble(id = rep(1:6, each = 10), idx = rep(1:10, 6), type = rep(c('A', 'B'), each = 10, times = 3), value = runif(60, 1, 5), rollAgg = 0.0)
#test mean/sum function on single 'id', and assign result to 'rollAgg' column
d <- df[df$id==2,]
z <- zoo(d$value, order.by = d$idx)
par <- d$type[1]
d$rollAgg <- (rollapply(z, 5, mean_sum, b = (par == 'A'), fill = NA, align = 'right'))
#prepare split data
by_id <- split(df, df$id)
#assign result to pre-assigned matrix
result <- as_tibble(matrix(data=0.0, nrow = 10, ncol = 6, dimnames=list(NULL,seq(1,6,1))))
for (i in seq_along(by_id)){
par <- by_id[[i]]$type[1]
z <- zoo(by_id[[i]]$value, order.by = by_id[[i]]$idx)
result[[i]] <- rollapply(z, 5, mean_sum, b = (par == 'A'), fill = NA, align = 'right')
}
#... which works - columns are alternating mean() and sum():
> head(result, 10)
# A tibble: 10 x 6
`1` `2` `3` `4` `5` `6`
<S3: zoo> <S3: zoo> <S3: zoo> <S3: zoo> <S3: zoo> <S3: zoo>
1 NA NA NA NA NA NA
2 NA NA NA NA NA NA
3 NA NA NA NA NA NA
4 NA NA NA NA NA NA
5 2.702983 14.35262 2.308507 16.58130 2.808490 14.63715
6 2.263146 13.47958 2.026396 14.90904 2.733020 14.75438
7 2.757074 15.46849 2.073545 16.27923 2.508627 14.56983
8 3.135715 14.84012 2.003807 13.15344 2.834664 14.33360
9 3.348647 15.67731 2.377744 14.19039 2.584147 16.21944
10 3.907222 14.40763 2.520130 14.86086 2.915271 15.48656
#try to assign result direct to split data, without success...
for (i in by_id){
par <- i$type[1]
z <- zoo(i$value, order.by = i$idx)
i$rollAgg <- rollapply(z, 5, mean_sum, b = (par == 'A'), fill = NA, align = 'right')
}
# finally, not sure how to unsplit() by_id to revert to original df...