Хобрук: Ваш путь к мастерству в программировании

Функция добавления строк к фрейму данных на основе предыдущих значений переменных в R

Я пытаюсь создать функцию, которая позволяет мне добавлять строки в существующий фрейм данных на основе переменных из самой предыдущей строки (непосредственно выше), несколько раз.

#Here's what I'm starting with 

Balance <- c(25000)
Pmt <- c(1500)
Interest <- c(.05)
DF <- data.frame(Balance,Pmt,Interest)
DF  
   Balance Pmt Interest
1   25000 100     0.05

Например, я хотел бы видеть добавленные следующие 4 строки, в которых «Баланс» новой строки равен ((Balance-Pmt) * (1 + Inerest)) предыдущей строки, а «Pmt» и Строки «по интересам» остаются неизменными.

# Manually
DF[2,1] <- (DF[1,1] - DF[1,2])*(1+DF[1,3])
DF[2,2] <- DF[1,2]
DF[2,3] <- DF[1,3]
D
  Balance  Pmt Interest
1   25000 1500     0.05
2   24675 1500     0.05

Очевидно, я хотел бы повторить это столько раз, сколько я хотел бы, без необходимости вручную ссылаться на предыдущую строку. Мне нужна функция, которая позволяет мне добавлять строки во фрейм данных столько раз, сколько я хочу, следуя той же логике. Любая помощь приветствуется!

29.06.2016

Ответы:


1

Вместо того, чтобы строить фрейм данных построчно, что будет очень неэффективно, вы можете настроить фрейм данных с учетом конечного размера. В этом примере вы знаете, что запустите этот процесс три раза, чтобы в итоге получить четыре строки. Сделайте этот фрейм данных первым, чтобы все остальное было проще и быстрее:

DF2 <- 'row.names<-'(DF[rep(1,4),], NULL)
DF2$Balance <- Reduce(function(x,y) (x - y)*(1+DF2[1,3]), DF2[-1,2], init=DF[1,1], acc=TRUE)
DF2
#    Balance  Pmt Interest
# 1 25000.00 1500     0.05
# 2 24675.00 1500     0.05
# 3 24333.75 1500     0.05
# 4 23975.44 1500     0.05

Самостоятельная работа: как работает Reduce?

Reduce - это функция более высокого уровня, которая работает уникальным образом и требует практики, чтобы овладеть ею. Он состоит из двух основных частей: 1) функции с двумя аргументами и 2) одного вектора *. Это странная часть. Ему нужна функция с двумя аргументами и одним вектором. Сначала это не имеет смысла. Как он проходит через один вектор с функцией, которой нужны два аргумента? Пример:

#one vector
x <- c(2,3,4,5)

#function with two arguments
multiply <- function(a, b)  {a * b}

Это вектор от 2 до 5 и простая функция, которая принимает два числа и умножает их. Reduce примет эти два объекта и сделает следующее:

Reduce(multiply, x) #<- this
#is the same as
ans1 <- multiply(2, 3) 
ans2 <- multiply(ans1, 4)
ans3 <- multiply(ans2, 5)

Он прошел через вектор c(2,3,4,5), взял первые две части (2 и 3) и вызвал на них функцию. Затем он взял этот ответ и ввел третий элемент x (4) для запуска функции, затем взял этот ответ и запустил его с четвертым элементом (5).


В вашем примере мы использовали его для прохождения первого баланса и платежей:

#one vector
x <- c(25000, 1500, 1500, 1500)

#function with two arguments
f <- function(a,b) (a - b)*(1 + 0.05)

Посмотрим, что он сделал внутри:

Reduce(f, x) #what we did
#internally Reduce did this
ans1 <- (25000 - 1500) * (1 + 0.05)
ans2 <- (ans1 - 1500) * (1 + 0.05)
ans3 <- (ans2 - 1500) * (1 + 0.05)

Это дало нам желаемый процесс. Это идея того, что мы сделали. Чтобы полностью завершить наше обсуждение, мы добавили два дополнительных аргумента, которые помогли нам получить желаемый результат. accumulate=TRUE и init=DF[1,1]. Первый просто сообщает Reduce, что нам нужен каждый последующий ответ, а не только последний. Второй сообщает Reduce, с какого значения мы хотим начать. Чтобы показать, что сделал init:

#Supply vector for function
x <- DF[-1,2]
x
[1] 1500 1500 1500

#We need the initial balance
#init=DF[1,1] does: 
[1] 25000 1500 1500 1500

Reduce также может принимать список, но сначала мы должны достичь мастерства вектора, а затем ввести методы списка.

29.06.2016

2

Используя пакет tvm: Time Value of Money Functions:

library(tvm)

n <- 5
rem(cf = rep(1500, n), amt = 25000, r = 0.05)
# [1] 24750.00 24487.50 24211.88 23922.47 23618.59
29.06.2016
  • Результаты разные. Похоже, rem использует другой вид вычислений amt * (1 + r)^t - sum(cf[1:t] * (1 + r)^(t - (1:t))) 29.06.2016

  • 3

    Создание набора данных:

        Balance <- c(25000)
        Pmt <- c(1500)
        Interest <- c(.05)
        DF <- data.frame(Balance,Pmt,Interest)
        DF
    1   25000 100     0.05
    

    Затем используйте функцию, скажем, n = 10 раз:

    > for(i in 2:10){
    +   DF[i,1] <- (DF[i-1,1] - DF[i-1,2])*(1+DF[i-1,3])
    +   DF[i,2] <- DF[i-1,2]
    +   DF[i,3] <- DF[i-1,3]
    + }
    > DF
        Balance  Pmt Interest
    # 1  25000.00 1500     0.05
    # 2  24675.00 1500     0.05
    # 3  24333.75 1500     0.05
    # 4  23975.44 1500     0.05
    # 5  23599.21 1500     0.05
    # 6  23204.17 1500     0.05
    # 7  22789.38 1500     0.05
    # 8  22353.85 1500     0.05
    # 9  21896.54 1500     0.05
    # 10 21416.37 1500     0.05
    

    Вы можете заменить 10 на 100 или 1000 в зависимости от того, сколько раз вы хотите запускать эту функцию.

    29.06.2016
  • Это именно то, что я искал. Спасибо за помощь! 01.07.2016
  • Добро пожаловать! Может быть, вы примете это как ответ :) 01.07.2016

  • 4

    Вы можете использовать эту функцию

    add_function <- function(n) invisible(replicate(n,{DF <<- rbind(DF,DF[nrow(DF),],make.row.names = F);DF[nrow(DF),1] <<- (DF[nrow(DF)-1,1]-DF[nrow(DF)-1,2])*(1+DF[nrow(DF)-1,3])}))
    

    Просто укажите значение n

    29.06.2016
    Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.