Эффективно применять темп роста к начальному значению для различных темпов роста в течение многих лет - PullRequest
0 голосов
/ 14 марта 2020

У меня большой набор данных о будущих темпах роста и начальное значение для каждого человека.

Я хочу умножить скорость роста при t = 0 на начальное значение (t = 0), чтобы получить значение при t = 1. Это значение t = 1, я хочу умножить на скорость роста при t = 1 и так далее.

В настоящее время я делаю это с al oop, но, учитывая, что у меня много людей в течение длительного периода времени, это очень медленно, и я чувствую, что должен быть более умный (и более элегантный) способ делая это.

Я бы хотел сделать это, используя функции dplyr .

#Create a sample df
df <- data.frame(id=rep(c("A","B"),each=5),
           year=rep(1:5,2),
           value = NA)

set.seed(123)
growth_rates <- data.frame(id=rep(c("A","B"),each=5),
                           year=rep(1:5,2),
                           value = runif(10,0.95,1.1))

# pick an initial value (in reality this is given)
df[df$year==1&df$id=="A","value"] <- 5
df[df$year==1&df$id=="B","value"] <- 7

for (i in 2:5){
  df[df$year == i,"value"] <- df[df$year == i-1,"value"]*growth_rates[growth_rates$year == i-1,"value"]
}

Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Мы можем использовать accumulate из purrr после назначения начальных значений в каждой группе.

library(dplyr)
library(purrr)

initial_value <- c(5, 7)
growth_rates$ans[!duplicated(df$id)] <- initial_value


growth_rates %>%
   group_by(id) %>%
   mutate(ans = accumulate(value[-n()], `*`, .init = first(ans)))


#   id     year value   ans
#   <fct> <int> <dbl> <dbl>
# 1 A         1 0.993  5   
# 2 A         2 1.07   4.97
# 3 A         3 1.01   5.30
# 4 A         4 1.08   5.36
# 5 A         5 1.09   5.81
# 6 B         1 0.957  7   
# 7 B         2 1.03   6.70
# 8 B         3 1.08   6.89
# 9 B         4 1.03   7.47
#10 B         5 1.02   7.72
1 голос
/ 14 марта 2020

Вот точное решение dplyr, использующее lag на cumprod из growth_rates:

initial_vals <- c(5, 7)

growth_rates %>%
  group_by(id) %>% 
  mutate(cumulative = lag(cumprod(value), default = 1)) %>%
  mutate(value = cumulative * initial_vals[match(id, c("A", "B"))]) %>%
  select(-cumulative)
#> # A tibble: 10 x 3
#> # Groups:   id [2]
#>    id     year value
#>    <fct> <int> <dbl>
#>  1 A         1  5   
#>  2 A         2  4.97
#>  3 A         3  5.30
#>  4 A         4  5.36
#>  5 A         5  5.81
#>  6 B         1  7   
#>  7 B         2  6.70
#>  8 B         3  6.89
#>  9 B         4  7.47
#> 10 B         5  7.72

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