Начисление амортизации, остаточной стоимости и новых займов по номинальной стоимости - PullRequest
0 голосов
/ 07 марта 2020

У меня есть данные «myinput», которые я хотел бы использовать для получения «myoutput».

myinput <- data.frame("Date" = c("1997-03-31", "1997-06-30", "1997-09-30", "1997-12-31", "1998-03-31"), "Face value" = c(15, 10, 12, 7, 7))

myoutput <- data.frame("Date" = c("1997-03-31", "1997-06-30", "1997-09-30", "1997-12-31", "1998-03-31"), "Face value" = c(15, 10, 12, 7, 7), "Amortisation" = c(0, 7.5, 8.75, 6.625, 6.1875), "Remaining value" = c(0, 7.5, 1.25, 5.375, 0.8125), "New loans" = c(15, 2.5, 10.75, 1.625, 6.1875))
  • Срок погашения всех ссуд составляет шесть месяцев.
  • Мы предполагаем, что новые ссуды на первую дату являются номинальной стоимостью на первую дату, то есть 15. Таким образом, каждая амортизация представляет собой сумму новых кредитов двух предыдущих периодов, разделенную на два, например, амортизация на дату 1998-03-31 гг. равна (10,75 + 1,625) /2.
  • Кроме того, каждая оставшаяся стоимость равна сумма всех предыдущих новых кредитов (за исключением сегодняшнего нового кредита), вычитаемая из совокупной суммы амортизаций (включая сегодняшнюю амортизацию). Например, оставшееся значение на дату 1998-03-31 составляет (15 + 2,5 + 10,75 + 1,625) - (0 + 7,5 + 8,75 + 6,625 + 6,1875).
  • Наконец, новые кредиты (после первое свидание) - это текущая номинальная стоимость за вычетом сегодняшней оставшейся стоимости.

Когда я делаю это в Excel, все работает хорошо, но мне трудно делать то же самое в R.

Любая помощь в том, как я могу написать этот код, будет очень полезной. оценили. Спасибо.

* Расширенный набор данных *

Я расширил свой набор данных, включив в него несколько групп (группа 1, группа 2 и т. Д. c). Каждая группа содержит номинал для каждой даты. Данные структурированы следующим образом:

df <- data.frame("Date" = c(2001, 2002,  2003, 2001, 2002,  2003, 2001, 2002, 2003),
                 "Face.value" = c(2, 5,  2, 3, 6, 4, 6, 7, 3),
                  "Group" = c(1, 1, 1, 2, 2, 2, 3, 3, 3))

Мне нужно запустить итерацию, предоставленную Стефаном для всех групп. Другими словами, мне нужно найти амортизацию, остаточную стоимость и новые кредиты для каждой группы и каждой даты. Есть какой-либо способ сделать это? Спасибо.

* Пример *

df <- data.frame("Date" = c(2001, 2002, 2003, 2001, 2002,  2003, 2001, 2002, 2003, 2001, 2002, 2003, 2004, 2005),
                 "Face.value" = c(2, 5,  2, 3, 6, 4, 6, 7, 3, 0, 3, 0, 5, 7),
                 "Group" = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4))

comp_results <- function(input) {
  ## input
  results <- input
  ## add results columns + temporary helper vars for New loans in previous periods
  results[c("Amortisation", "Remaining.value", "New.loans", "New.loans.lag", "New.loans.lag2","New.loans.lag3","New.loans.lag4","New.loans.lag5","New.loans.lag6","New.loans.lag7","New.loans.lag8")] <- 0
  # Init value for new.loans in first period
  results[1, "New.loans"] <- results[1, "Face.value"]
  # Iterate over periods 2, ...
  if (nrow(results) > 1) {
    for (i in seq(2, nrow(results))) {
      # Put the formulas in cells
      results[i, "New.loans.lag"] <- results[i - 1, "New.loans"]
      results[i, "New.loans.lag2"] <- results[i - 1, "New.loans.lag"]
      results[i, "New.loans.lag3"] <- results[i - 1, "New.loans.lag2"]
      results[i, "New.loans.lag4"] <- results[i - 1, "New.loans.lag3"]
      results[i, "New.loans.lag5"] <- results[i - 1, "New.loans.lag4"]
      results[i, "New.loans.lag6"] <- results[i - 1, "New.loans.lag5"]
      results[i, "New.loans.lag7"] <- results[i - 1, "New.loans.lag6"]
      results[i, "New.loans.lag8"] <- results[i - 1, "New.loans.lag7"]
      # If Face Value in previous period = 0: No amortisation takes place
      if (results[i - 1, "Face.value"] > 0) {
        results[i, "Amortisation"] <- (results[i, "New.loans.lag"] + results[i, "New.loans.lag2"] + results[i, "New.loans.lag3"] + results[i, "New.loans.lag4"] + results[i, "New.loans.lag5"] + results[i, "New.loans.lag6"] + results[i, "New.loans.lag7"] + results[i, "New.loans.lag8"]) * (3/24)
      } else {
        results[i, "Amortisation"] <- 0
      }
      results[i, "Remaining.value"] <- sum(results[1:i, "New.loans.lag"]) - sum(results[1:i, "Amortisation"])
      results[i, "New.loans"] <- results[i, "Face.value"] - results[i, "Remaining.value"]
      # If Amortisation rule results in negative new loans: Adjust the amortisation
      if (results[i, "New.loans"] < 0 & results[i, "Face.value"] == 0)  {
        results[i, "New.loans"] <- 0
        results[i, "Remaining.value"] <- results[i, "Face.value"]
        results[i, "Amortisation"] <- sum(results[1:i, "New.loans.lag"]) - 
          sum(results[1:(i-1), "Amortisation"]) -
          results[i, "Remaining.value"]
      }
    }
  }
  # Drop temporary vars
  results[c("New.loans.lag", "New.loans.lag2", "New.loans.lag3", "New.loans.lag4", "New.loans.lag5", "New.loans.lag6", "New.loans.lag7", "New.loans.lag8")] <- NULL
  # Output
  results
}

df_split <- split(df, df$Group)
df_results <- lapply(df_split, comp_results)
df_results <- bind_rows(df_results)

1 Ответ

0 голосов
/ 07 марта 2020

Попробуйте это. В некотором смысле мое решение R очень похоже на Excel. Добавьте столбцы и поместите формулы в ячейки. (; Для вычисления в расширенном наборе данных я просто поместил «формулу» в функцию, которая затем может быть применена в группе:

df <- data.frame("Date" = c(2001, 2002, 2003, 2001, 2002,  2003, 2001, 2002, 2003, 2001, 2002, 2003, 2004, 2005),
                 "Face.value" = c(2, 5,  2, 3, 6, 4, 6, 7, 3, 0, 3, 0, 5, 7),
                 "Group" = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4))


# Computes the number of lags to the period where face.value was last zero or to the number of periods
comp_lag <- function(x) {
  x_zero <- which(x <= 0)
  if (length(x_zero) > 0) {
    length(x) - max(x_zero)
  } else {
    length(x)
  }

}

comp_results <- function(input) {
  ## input
  results <- input
  ## add results columns + temporary helper vars for New loans in previous periods
  # Use paste0 to create variables for lags
  # OBS: Rename New.loans to New.loans.lag.0: Simplifies the loop
  results[c("Face.value.lag.1", "Amortisation", "Remaining.value", paste0("New.loans.lag.", 0:8))] <- 0
  # Init value for new.loans in first period
  results[1, "New.loans.lag.0"] <- results[1, "Face.value"]
  # Iterate over periods 2, ...
  if (nrow(results) > 1) {
    for (i in seq(2, nrow(results))) {
      results[i, "Face.value.lag.1"] <- results[i - 1, "Face.value"]
      # Put the formulas in cells
      # Assign values to lag vars using paste0
      for (lag in seq(8)) {
        results[i, paste0("New.loans.lag.", lag)] <- results[i - 1, paste0("New.loans.lag.", lag - 1)]
      }
      num_lag <- comp_lag(results[1:i, "Face.value"])
      # If Face Value in previous period = 0: No amortisation takes place
      if (results[i - 1, "Face.value"] > 0) {
        results[i, "Amortisation"] <- sum(results[i, paste0("New.loans.lag.", 1:num_lag)]) * (3/24)
      } else {
        results[i, "Amortisation"] <- 0
      }
      results[i, "Remaining.value"] <- sum(results[1:i, "New.loans.lag.0"]) - sum(results[1:i, "Amortisation"])
      results[i, "New.loans.lag.0"] <- results[i, "Face.value"] - results[i, "Remaining.value"]
      # If Amortisation rule results in negative new loans: Adjust the amortisation
      # Drop the condition Face value = 0
      if (results[i, "New.loans.lag.0"] < 0)  {
        results[i, "New.loans.lag.0"] <- 0
        results[i, "Remaining.value"] <- results[i, "Face.value"]
        results[i, "Amortisation"] <- sum(results[1:i, "New.loans.lag.1"]) - 
          sum(results[1:(i-1), "Amortisation"]) -
          results[i, "Remaining.value"]
      }
    }
  }
  # Drop temporary vars
  results[c("Face.value.lag.1", paste0("New.loans.lag.", 1:8))] <- NULL
  names(results)[names(results) %in% "New.loans.lag.0"] <- "New.loans"
  # Output
  results
}

df_split <- split(df, df$Group)
df_results <- lapply(df_split, comp_results)
df_results <- dplyr::bind_rows(df_results)
df_results
#>    Date Face.value Group Amortisation Remaining.value New.loans
#> 1  2001          2     1        0.000           0.000     2.000
#> 2  2002          5     1        0.250           1.750     3.250
#> 3  2003          2     1        3.000           2.000     0.000
#> 4  2001          3     2        0.000           0.000     3.000
#> 5  2002          6     2        0.375           2.625     3.375
#> 6  2003          4     2        2.000           4.000     0.000
#> 7  2001          6     3        0.000           0.000     6.000
#> 8  2002          7     3        0.750           5.250     1.750
#> 9  2003          3     3        4.000           3.000     0.000
#> 10 2001          0     4        0.000           0.000     0.000
#> 11 2002          3     4        0.000           0.000     3.000
#> 12 2003          0     4        3.000           0.000     0.000
#> 13 2004          5     4        0.000           0.000     5.000
#> 14 2005          7     4        0.625           4.375     2.625

Создано в 2020-04-20 с помощью Представить пакет (v0.3.0)

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