R - Accumulated inflation

Asked

Viewed 129 times

0

Hello, I would like a help in the following mission, based on the IPCA-monthly table (historical series), add a field with annual accumulated inflation, where the process resumes each year.

For the calculation of accumulated inflation, compound interest is used, where we have the following formula: Cumulative inflation = (((1 + (month inflation/100)) * previous cumulative inflation) + month inflation)

I tried to use the simple sum, but the end result is divergent from the final annual result, so the need to use compound interest.

My dataset, or data.frame, (listDF) input has the following fields: 1- Date: (month of establishment) 2- Inflation: Inflation of the month.

In this case I would like to have as output, a set date equal to the added entry of a column with the accrued interest, where it would be calculated by year, that is, at each beginning of year, the counting resumes. Final dataset:

1- Date: (month of establishment) 2- Inflation: Inflation of the month. 3 - Accumulated inflation: Accumulated inflation during the calculation year.

I tried to use the script below in Rstudio, but it does not create the field, nor the error message.

As I will perform the process in several sources, I imagined using a function to make it cleaner and more functional.

Input dataset (example):

lista <- list(a = c('1991-10-01', '1991-11-01', '1991-12-01', '1992-01-01','1992-02-01'), 
              b = c(0.5, 0.6, 0.8, 1.2, 1.4))

Where "a" is the month of retention and "b" is inflation.

unsuccessful attempt (Does not create field) and gives no error message.

Obs.1: I would like it to be via function because the process will be carried out in several tables. Note.2: I couldn’t find a function/package with this function

lista <- list(a = c('1991-10-01', '1991-11-01', '1991-12-01', '1992-01-01','1992-02-01'), 
              b = c(0.5, 0.6, 0.8, 1.2, 1.4))
lista

listaDF <- as.data.frame(lista)

Acum <- function(){
  ano1 = format(df$Data[1], format = "%Y")
  ano1 = as.integer(ano1)
  anomes <- paste(ano1, mes)
  anomes
  jur1 = 0
  acum_jur = 0
  #df$acum_jur <- vector(df, length(df$data))
  #i = 1;
  for (x in df$Data){
    dia3 = as.Date(x)
    ano2 = (format(dia3, format = "%Y"))
    ano2 <- as.integer(ano2)
    mes <- format(dia3, format = "%m")
    jur = df$tx_jur[df$Data == dia3]
    if (ano2 == ano1)
    {
      anomes <- paste(ano2, mes)
      acum_jur1 = (((1 + (jur/100)) * acum_jur) + jur)
      acum_jur <- acum_jur1
      df$tx_acum[df$Data == dia3] <- round(acum_jur1, 2)
      #df$acum_jur[[i]] <- round(acum_jur1, 2)
    }
    else
    {
      ano1 = ano1 + 1
      anomes <- paste(ano2, mes)
      acum_jur1 = df$tx_jur[df$Data == dia3]
      acum_jur <- acum_jur1
      df$tx_acum[df$Data == dia3] <- round(acum_jur1, 2)
      #df$acum_jur[[i]] <- round(acum_jur1, 2)
    }
  }
}

listaDF$new_column <- Acum()
listaDF
  • Hello PNETO. Put an example of data.frame complete you need as output. This function you made: Does it calculate wrong? Does it not calculate? Is the inflation of the year not just adding up all the values of the year? See tips on how to improve your question here and here

1 answer

0


I believe the function cumprod already makes the calculation of the accumulated rate you seek:

taxas <- c(0.5, 0.6, 0.8)
taxas
# [1] 0.5 0.6 0.8
taxas_acumuladas <- cumprod((taxas/100) + 1) - 1
taxas_acumuladas
# [1] 0.00500000 0.01103000 0.01911824

So the hard part of your problem would be dividing the data into blocks. I made a solution dividing into blocks with split which appears further down, but then I realized that you get the same result more simply by grouping by year:

library(tidyverse)

df <- tibble(
    a = c('1991-10-01','1991-11-01','1991-12-01','1992-01-01','1992-02-01'),
    b = c(0.5, 0.6, 0.8, 1.2, 1.4)
  )

df <- df %>%
  mutate(a = as.Date(a),
         y = year(a)) %>%
  arrange(a)

# solução agrupando...
sol1 <- df %>% 
  group_by(y) %>% 
  mutate(
    tx_acum = cumprod((b/100)+1)-1
  )

# ou dividindo em blocos...
split_df <- split(df, df$y)
cum_taxes <- map(split_df, ~ (cumprod((.$b/100) + 1) - 1))
sol2 <- do.call(rbind,
              map2(split_df, cum_taxes, ~ tibble(.x, cum_taxes = .y)))

Browser other questions tagged

You are not signed in. Login or sign up in order to post.