Несколько дней назад я опубликовал этот вопрос: Как создать динамический столбец в R? (ссылка, чтобы вы могли лучше понять, о чем я спрашиваю), чтобы создать «динамический» столбец, и решение заключалось в использовании функции Reduce (). Теперь я хочу в основном сделать то же самое (рассчитать изменение баланса, взяв за основу предыдущую строку), но с подмножествами фрейма данных, отфильтрованными по определенному столбцу. Короче говоря, я хочу выполнить тот же расчет, но только для групп, поэтому у меня есть значение X в качестве начального капитала для групп A, B и C, и изменение баланса будет "сброшено" до начального капитала для каждая группа.
Я знаю, что приведенное выше объяснение не так ясно, поэтому вот быстрая упрощенная версия того, чего я хотел бы достичь:
class <- c("a", "a", "b", "b", "c", "c")
profit <- c(10, 15, -5, -6, 20, 5)
change <- profit / 1000
balance <- c(1010, 1025, 1020, 1014, 1036, 1039)
data <- data.frame(class, profit, change, balance)
a <- data %>% filter(class == "a")
b <- data %>% filter(class == "b")
c <- data %>% filter(class == "c")
start_capital = 1000
a_bal <- Reduce(function(x, y) x + x*y, a$change, init = start_capital, accumulate = TRUE)[-1]
a <- mutate(a, balance = a_bal,
profit = balance - (balance / (1 + change)))
b_bal <- Reduce(function(x, y) x + x*y, b$change, init = start_capital, accumulate = TRUE)[-1]
b <- mutate(b, balance = b_bal,
profit = balance - (balance / (1 + change)))
c_bal <- Reduce(function(x, y) x + x*y, c$change, init = start_capital, accumulate = TRUE)[-1]
c <- mutate(c, balance = c_bal,
profit = balance - (balance / (1 + change)))
data <- bind_rows(a, b, c)
class profit change balance
1 a 10.00 0.010 1010.00
2 a 15.15 0.015 1025.15
3 b -5.00 -0.005 995.00
4 b -5.97 -0.006 989.03
5 c 20.00 0.020 1020.00
6 c 5.10 0.005 1025.10
Очевидно, есть более эффективный способ сделать это, но я пытаюсь его найти. Мой подход к решению этой проблемы заключался бы в создании функции, которая принимает в качестве входных данных фрейм данных и класс, в котором я хочу применить вычисления, и выводить фрейм данных с измененными значениями для этой группы, чтобы затем использовать некоторую функцию применения для выполнения операция на всех группах. Но перед тем, как приступить к созданию этой функции, я бы предпочел спросить, есть ли способ сделать это с помощью существующей. Я думал об использовании group_by () вместе с оператором конвейера, но поскольку Reduce () не из библиотеки tidyverse, это не сработает.