У меня есть список транзакций для многих людей.Я хочу выяснить, когда каждый конкретный человек пересек определенное пороговое значение общих транзакций.
Вот пример того, что я уже сделал: Пример набора данных:
df <- data.frame(name = rep(c("a","b"),4),
dates = seq(as.Date("2017-01-01"), by = "month", length.out = 8), amt = 11:18)
setorderv(df, "name")
Это даетмне следующий кадр данных
name dates amt
1 a 2017-01-01 11
3 a 2017-03-01 13
5 a 2017-05-01 15
7 a 2017-07-01 17
2 b 2017-02-01 12
4 b 2017-04-01 14
6 b 2017-06-01 16
8 b 2017-08-01 18
Затем я написал следующий код, чтобы найти совокупные суммы
df$cumsum <- ave(df$amt, df$name, FUN = cumsum)
Это дает мне следующий кадр данных:
name dates amt cumsum
1 a 2017-01-01 11 11
3 a 2017-03-01 13 24
5 a 2017-05-01 15 39
7 a 2017-07-01 17 56
2 b 2017-02-01 12 12
4 b 2017-04-01 14 26
6 b 2017-06-01 16 42
8 b 2017-08-01 18 60
Теперь я хочу знать, когда каждый человек пересек 20 и 40. Я написал следующий код, чтобы выяснить это:
names <- unique(df$name)
for (i in seq_along(names)){
x1 <- Position(function(x) x >= 20, df$cumsum[df$name == names[i]])
x2 <- Position(function(x) x >= 40, df$cumsum[df$name == names[i]])
result_df[i,] <- c(df$name[i],
df[df$name == names[i],2][x1],
df[df$name == names[i],2][x2])
}
Этот код проверяет, где были пересечены пороги, и сохраняет номер строки в переменной.Затем извлекает значение из этой строки второго столбца и сохраняет его в другом фрейме данных.
Проблема в том, что этот код действительно медленный.В моем наборе данных более 200 000 человек и более 10 миллионов строк.Выполнение этого кода занимает около 25 секунд для первых 50 пользователей, что означает, что для всего набора данных может потребоваться около 30 часов.
Есть ли более быстрый способ сделать это?