Совокупные агрегаты в пределах тидиверса - PullRequest
0 голосов
/ 30 мая 2018

скажем, у меня есть tibble (или data.table), который состоит из двух столбцов:

a <- tibble(id = rep(c("A", "B"), each = 6), val = c(1, 0, 0, 1 ,0,1,0,0,0,1,1,1))

Кроме того, у меня есть функция с именем myfun, которая принимает числовой вектор произвольной длины в качестве входных данныхи возвращает одно число.Например, вы можете думать о myfun как о стандартном отклонении.

Теперь я хотел бы создать третий столбец для моего tibble (называемого результатом), который содержит выходные данные myfun, примененные кval накопил и сгруппировал относительно id.Например, первая запись результата должна содержать mfun(val[1]).Вторая запись должна содержать myfun(val[1:2]) и т. Д.Я хотел бы реализовать накопленную версию myfun.

Конечно, существует множество простых решений за пределами tidyverse с использованием циклов, а что нет.Но мне было бы интересно найти решение в рамках tidyverse или в рамках data.table.

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Можно использовать zoo::rollapplyr с динамической шириной (vector containing width).Для подготовки динамической ширины для каждой группы можно использовать 1:n() или seq(n()).

Давайте применим его для функции sd, используя данные, предоставленные OP:

library(dplyr)
library(zoo)

a %>% group_by(id) %>%
  mutate(y = rollapplyr(val, 1:n(), sd ))

#   # Groups: id [2]
#   id      val      y
#   <chr> <dbl>  <dbl>
#  1 A      1.00 NA    
#  2 A      0     0.707
#  3 A      0     0.577
#  4 A      1.00  0.577
#  5 A      0     0.548
#  6 A      1.00  0.548
#  7 B      0    NA    
#  8 B      0     0    
#  9 B      0     0    
# 10 B      1.00  0.500
# 11 B      1.00  0.548
# 12 B      1.00  0.548
0 голосов
/ 30 мая 2018

Вы могли бы сделать это следующим образом:

library(tidyverse)

a %>% 
  group_by(id) %>% 
  mutate(y = map_dbl(seq_along(val),~sd(val[1:.x]))) %>%
  ungroup

# # A tibble: 12 x 3
#       id   val         y
#    <chr> <dbl>     <dbl>
#  1     A     1        NA
#  2     A     0 0.7071068
#  3     A     0 0.5773503
#  4     A     1 0.5773503
#  5     A     0 0.5477226
#  6     A     1 0.5477226
#  7     B     0        NA
#  8     B     0 0.0000000
#  9     B     0 0.0000000
# 10     B     1 0.5000000
# 11     B     1 0.5477226
# 12     B     1 0.5477226

Объяснение

Сначала мы часто группируем, как часто, с цепями tidyverse, затем используем mutate,а не summarize, поскольку мы хотим сохранить те же самые неагрегированные строки.

Функция map_dbl здесь используется для зацикливания вектора конечных индексов.seq_along(val) будет здесь 1:6 для обеих групп.

Используя функции из семейства карт, мы можем использовать нотацию ~, которая предполагает, что первый параметр функции называется .x.

Проходя по этим индексам, мы сначала вычисляем sd(val[1:1]), который равен sd(val[1]), что составляет NA, затем sd(val[1:2]) и т. Д.

map_dbl возвращает по расчету вектор doubles, и они укладываются в столбец y.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...