Генерация индекса значений для составления, но игнорирование начального значения в масштабируемой форме - PullRequest
1 голос
/ 27 мая 2019

Я пытаюсь сгенерировать индекс, полученный из возвращаемых данных.

Новый столбец, который я хочу сгенерировать, будет получен, взяв 100 и затем составив это.Для этого примера:

первое значение = 100

второе значение = первое значение * (1 + 10/100) = 110

третье значение = второе значение * (1+20/100) = 132 и т. Д.

Обратите внимание, что первое возвращаемое значение 5 необходимо игнорировать.Я знаю, что могу просто перезаписать это, чтобы выполнить то, что я хочу, но мне было интересно, есть ли более элегантный способ получить желаемый результат.

Я близок к тому, чтобы получить то, что я хочу, но мне нужно игнорироватьпервое возвращение 5. Ожидаемый результат new_col будет 100, 110, 132.

**Reproducible example**

    # Load package
    library(tidyverse)

    # Create data
    df <- data.frame(asset = c("A", "A", "A"), return = c(5,10,20))
    df

# Generate new column
test <- df %>%
  mutate(new_col = 100) %>%   #initialize
  mutate(new_col = ifelse(row_number(new_col) == 1,
                          new_col,
                          lag(new_col, 1) * cumprod((1 + return/100))
                          )
         )
test

Заранее спасибо!

1 Ответ

1 голос
/ 27 мая 2019

Опция будет accumulate

library(tidyverse)
df %>% 
   mutate(newcol = accumulate(return[-1], ~ .x* (1 + .y/100), .init = 100))
#  asset return newcol
#1     A      5    100
#2     A     10    110
#3     A     20    132

Или используя cumprod

df %>% 
    mutate(newcol = cumprod( c(100, 1 + return[-1]/100)))

или аналогичный параметр в base R

Reduce(function(x, y) x * (1 + y/100), df$return[-1], init = 100, accumulate = TRUE)
#[1] 100 110 132

Или с for петлей

df$newcol[1] <- 100
for(i in 2:nrow(df)) df$newcol[i] <- df$newcol[i-1] * (1 + df$return[i]/100)

Для нескольких столбцов используйте mutate_at

df1 %>% 
    mutate_at(vars(starts_with('return')), 
      list(newcol = ~  accumulate(.[-1], ~ .x * (1+ .y/100), .init = 100)))
#   asset return return2 return_newcol return2_newcol
#1     A      5      15           100            100
#2     A     10      12           110            112
#3     A     20      25           132            140

данные

df1 <- data.frame(asset = c("A", "A", "A"), 
      return = c(5,10,20), return2 = c(15, 12, 25))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...