Как ускорить вычисление / вставку столбца разности дат? - PullRequest
4 голосов
/ 31 октября 2011

Можете ли вы сделать этот код R быстрее? Не вижу, как это векторизовать. У меня есть фрейм данных следующим образом (пример строки ниже):

> str(tt)
'data.frame':   1008142 obs. of  4 variables:
 $ customer_id: int, visit_date : Date, format: "2010-04-04", ...

Я хочу вычислить разницу между visit_dates для клиента. Так что я делаю diff(tt$visit_date), но вынужден применять разрыв (NA) везде, где меняется customer_id, а разница не имеет смысла, например строка 74 ниже. Код внизу делает это, но занимает> 15 минут для набора данных строки 1M. Я также попробовал кусочно вычислить и cbind'ing подрезультат для customer_id (используя which()), что также было медленным. Какие-либо предложения? Благодарю. Я выполнил поиск SO, R-intro, R manpages и т. Д.

   customer_id visit_date visit_spend ivi
72          40 2011-03-15       18.38   5
73          40 2011-03-20       23.45   5
74          79 2010-04-07      150.87  NA
75          79 2010-04-17      101.90  10
76          79 2010-05-02      111.90  15

Код:

all_tt_cids <- unique(tt$customer_id)

# Append ivi (Intervisit interval) column
tt$ivi <- c(NA,diff(tt$visit_date))
for (cid in all_tt_cids) {
  # ivi has a discontinuity when customer_id changes
  tt$ivi[min(which(tt$customer_id==cid))] <- NA
}

(Интересно, можем ли мы создать логический индекс, где customer_id отличается от строки выше?)

1 Ответ

6 голосов
/ 31 октября 2011

для установки NA в соответствующих местах, вы снова можете использовать diff() и однострочный трюк:

> tt$ivi[c(1,diff(tt$customer_id)) != 0] <- NA

объяснение

давайте возьмем несколькоvector x

x <- c(1,1,1,1,2,2,2,4,4,4,5,3,3,3)

мы хотим извлечь такие индексы, которые начинаются с нового номера, т.е. (0,5,8,11,12).Для этого можно использовать diff().

y <- c(1,diff(x))
# y = 1  0  0  0  1  0  0  2  0  0  1 -2  0  0

и взять те индексы, которые не равны нулю:

x[y!=0] <- NA
...