Мы можем заменить ваш цикл функцией diff()
, которая вычисляет различия между смежными индексами в векторе, например:
> diff(c(1,3,6,10))
[1] 2 3 4
К этому мы можем добавить Inf
к различиям через c(Inf, diff(x))
.
Следующее, что нам нужно, это применить вышеуказанное к каждому user_id
индивидуально.Для этого есть много вариантов, но здесь я использую aggregate()
.Смущает, что эта функция возвращает фрейм данных с компонентом time
, который сам является матрицей.Нам нужно преобразовать эту матрицу в вектор, опираясь на тот факт, что в R столбцы матриц заполняются первыми.Наконец, мы добавляем и interval
столбец к входным данным в соответствии с вашей исходной версией функции.
interval <- function(x) {
diffs <- aggregate(time ~ user_id, data = x, function(y) c(Inf, diff(y)))
diffs <- as.numeric(diffs$time)
x <- within(x, interval <- diffs)
x
}
Вот немного расширенный пример с 3 временными точками на пользователя, чтобы проиллюстрировать вышеуказанную функцию:
> visit_log = data.frame(user_id = rep(1:5, 3), time = 1:15)
> interval(visit_log)
user_id time interval
1 1 1 Inf
2 2 2 Inf
3 3 3 Inf
4 4 4 Inf
5 5 5 Inf
6 1 6 5
7 2 7 5
8 3 8 5
9 4 9 5
10 5 10 5
11 1 11 5
12 2 12 5
13 3 13 5
14 4 14 5
15 5 15 5