Применение инкрементной функции к dplyr :: do () через group_by - PullRequest
0 голосов
/ 26 апреля 2018

У меня проблемы с применением dplyr :: do () через group_by при постепенном вычислении результатов для последовательности.

В более простом случае я мог бы использовать цикл for:

df <- data.frame(year = rep(2000:2002, 1), id = rep(letters[1], 3), obs1 = rep(1,3), obs2 = rep(1,3))

initialValue <- 5

for(i in 1:nrow(df)){
initialValue[i+1] <- initialValue[i] + df$obs1[i] + df$obs1[i] 
}

Таким образом, результатом является начальное значение, за которым следуют обновленные значения для 2000: 2002 годов в списке:

> initialValue
[1]  5  7  9 11

Но у меня много данных за несколько лет и несколько групп (идентификаторов). Я полагаю, что dplyr :: do () - это ответ:

library(dplyr)

df <- data.frame(year = rep(2000:2002, 3), id = rep(letters[1:3], 3), obs1 = rep(1,9), obs2 = rep(1,9))
initialValue <- 5

doCalc <- function(obs){
initialValue <- initialValue + sum(obs)
}

df %>%
  group_by(id) %>%
  do(new <- doCalc(obs = c(.$obs1, .$obs2)))

Ошибка:

Error: Results 1, 2, 3 must be data frames, not numeric

Я ожидаю, что для каждой группы будет список результатов за каждый год:

[[1]]
[1]  5  7  9 11

[[2]]
[1]  5  7  9 11

[[3]]
[1]  5  7  9 11

Так, как применить это постепенно в функции?

1 Ответ

0 голосов
/ 26 апреля 2018

Мы можем использовать accumulate из purrr

library(tidyverse)
df %>%
   group_by(id) %>% #assuming many groups are found in the original data
   mutate(val = list(accumulate(obs1, ~ .x + 2 *.y, .init = initialValue))) %>% 
  .$val
#[[1]]
#[1]  5  7  9 11

#[[2]]
#[1]  5  7  9 11

#[[3]]
#[1]  5  7  9 11

Или мы можем использовать Reduce из base R

unsplit(lapply(split(df, df$id), function(dat)  {
   dat$val <- list(Reduce(function(x, y) x + 2 *y, dat$obs1,
              accumulate = TRUE, init = initialValue))
   dat}), df$id)

данные

df <- data.frame(year = rep(2000:2002, 1), id = rep(letters[1], 3), 
           obs1 = rep(1,3), obs2 = rep(1,3))
initialValue <- 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...