Расчет текущих инвестиций в R (путем реинвестирования прибыли)

#r #loops #return #finance

#r #петли #Возврат #финансы

Вопрос:

У меня есть фрейм данных:

 > df
    date group return
1 197501     A  1.020
2 197502     A  1.050
3 197503     A  1.031
4 197504     A  0.970
5 197501     B  0.990
6 197502     B  1.023
7 197503     B  1.040
8 197504     B  1.050
 

Я хочу создать новую колонку «inv», указывающую на рост моих инвестиций, т. Е. Я инвестирую 1 000 000 в 197501, и затем мне нужно рассчитать доходность моих инвестиций (плюс доходность за прошлый месяц). Кроме того, у меня есть группы, означающие, что каждый раз, когда запускается новая группа, первая строка должна начинаться с 1 000 000 * return .

Это означает, что:

В строке 1 я хочу

 1,000,000 * 1.020 = 1,020,000 
 

В строке 2 я тогда хочу

 1,020,000 * 1.050 = 1,071,000
 

и т.д.

В строке 5 (группа b) я хочу

 1,000,000 * 0.990 = 990,000
 

В строке 6 (группа b) я хочу

 990,000 * 1.023 = 1,012,770
 

и т.д.

Конечный результат должен выглядеть следующим образом:

     date group return        inv
1 197501     A  1.020 1020000.00
2 197502     A  1.050 1071000.00
3 197503     A  1.031 1104201.00
4 197504     A  0.970 1071075.97
5 197501     B  0.990  990000.00
6 197502     B  1.023 1012770.00
7 197503     B  1.040 1053281.80
8 197504     B  1.050 1105945.84
 

Как я могу сделать это в R?

Ответ №1:

Мы можем использовать cumprod после выполнения операции группирования по

 library(dplyr)
df1 <- df %>% 
         group_by(group) %>%
         mutate(inv = 1000000 *cumprod(return)) %>%
         ungroup
 

-вывод

 df1
# A tibble: 8 x 4
#    date group return      inv
#   <int> <chr>  <dbl>    <dbl>
#1 197501 A       1.02 1020000 
#2 197502 A       1.05 1071000.
#3 197503 A       1.03 1104201 
#4 197504 A       0.97 1071075.
#5 197501 B       0.99  990000 
#6 197502 B       1.02 1012770 
#7 197503 B       1.04 1053281.
#8 197504 B       1.05 1105945.
 

Или с помощью base R

 df$inv <- with(df, 1000000 * ave(return, group, FUN = cumprod))
 

данные

 df <- structure(list(date = c(197501L, 197502L, 197503L, 197504L, 197501L, 
197502L, 197503L, 197504L), group = c("A", "A", "A", "A", "B", 
"B", "B", "B"), return = c(1.02, 1.05, 1.031, 0.97, 0.99, 1.023, 
1.04, 1.05)), class = "data.frame", row.names = c("1", "2", "3", 
"4", "5", "6", "7", "8"))