Могу ли я назначить результат векторной функции для разделения столбца данных таблицы? - PullRequest
0 голосов
/ 20 июня 2019

У меня есть некоторые аккуратные данные, содержащие идентичные серии длин '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...

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Если ваша цель - запустить rollapply на value отдельно для каждого id, тогда вместо split используйте ave:

b <- TRUE
roll <- function(x) rollapplyr(x, 5, mean_sum, b = b, fill = NA)
transform(df, rollAgg = ave(value, id, FUN = roll))

или

b <- TRUE
rollb <- function(b) {
  function(x) rollapplyr(x, 5, mean_sum, b = b, fill = NA)
}
transform(df, rollAgg = ave(value, id, FUN = rollb(b)))
0 голосов
/ 20 июня 2019

аккуратный раствор на основе роллмэна с dplyr и magrittr

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))

df %<>%
  group_by(id) %>%
  mutate(rollAgg=rollapply(value,5, mean_sum, b = (type[1] == 'A'), fill = NA, align="right"))
0 голосов
/ 20 июня 2019

О

не знаю, как отсоединить ...

Один короткий ответ с данными радужной оболочки:)

unsplit(split(x = iris, f = iris$Species), f = iris$Species)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...