Вычислить среднюю разницу между датами на основе условия в R - PullRequest
4 голосов
/ 10 марта 2020

У меня есть этот набор данных:

Date New_Renew
 2019-01-10 22:11:16  Renewing
 2019-02-23 00:21:48  Renewing
 2019-03-05 05:26:17  Renewing
 2019-04-18 15:05:10       NEW
 2019-04-18 15:07:52       NEW
 2019-04-26 11:32:25  Renewing
 2019-05-03 14:15:25  Renewing
 2019-05-08 21:10:08       NEW
 2019-05-16 13:35:57  Renewing
 2019-05-24 13:18:23  Renewing
 2019-06-01 12:42:21  Renewing
 2019-06-17 18:08:09  Renewing
 2019-06-26 13:40:29  Renewing
 2019-12-13 17:57:43  Renewing
 2020-01-03 11:49:14  Renewing
 2020-01-11 11:46:51  Renewing
 2020-01-14 21:08:08       NEW
 2020-01-18 21:14:30       NEW
 2020-01-21 16:08:37       NEW
 2020-01-28 11:41:44  Renewing
 2020-01-30 13:34:21  Renewing
 2020-02-03 13:29:37  Renewing
 2020-02-18 17:15:52  Renewing
 2020-02-20 13:37:52  Renewing
 2020-02-24 12:55:25  Renewing
 2020-02-26 21:13:38       NEW
 2020-03-04 13:23:41  Renewing
 2020-03-09 16:48:36  Renewing

Что мне нужно, когда переменная New_Renew равна NEW, чтобы вычислить среднее значение разницы между датами, связанными с NEW. Проще говоря, как часто пользователь совершает НОВУЮ транзакцию.

Ответы [ 4 ]

2 голосов
/ 10 марта 2020

Использование aggregate и diff. 60*24 преобразует текущие секунды в дни.

aggregate(Date ~ New_Renew, dat, function(x) mean(diff(x))/(60*24))
#  New_Renew         Date
# 1       NEW 52.38292438 
# 2  Renewing  0.01471444 

Или с tapply.

with(dat, tapply(Date, New_Renew, function(x) mean(diff(x))/(60*24)))
#         NEW    Renewing 
# 52.38292438  0.01471444 

Данные

dat <- structure(list(Date = structure(c(1547154676, 1550877708, 1551759977, 
1555592710, 1555592872, 1556271145, 1556885725, 1557342608, 1558006557, 
1558696703, 1559385741, 1560787689, 1561549229, 1576256263, 1578048554, 
1578739611, 1579032488, 1579378470, 1579619317, 1580208104, 1580387661, 
1580732977, 1582042552, 1582202272, 1582545325, 1582748018, 1583324621, 
1583768916), class = c("POSIXct", "POSIXt"), tzone = ""), New_Renew = c("Renewing", 
"Renewing", "Renewing", "NEW", "NEW", "Renewing", "Renewing", 
"NEW", "Renewing", "Renewing", "Renewing", "Renewing", "Renewing", 
"Renewing", "Renewing", "Renewing", "NEW", "NEW", "NEW", "Renewing", 
"Renewing", "Renewing", "Renewing", "Renewing", "Renewing", "NEW", 
"Renewing", "Renewing")), row.names = c(NA, -28L), class = "data.frame")
2 голосов
/ 10 марта 2020

Использование dplyr

library(dplyr)
df %>%
  filter(New_Renew=="NEW") %>%
  mutate(Date_next=lead(Date), duration=Date_next-Date) %>%
  summarise(mean=mean(duration, na.rm=TRUE))

# A tibble: 1 x 1
  mean         
  <drtn>       
1 75421.41 mins # ~ 52 days

Перед общим итогом:

# A tibble: 7 x 4
  Date                New_Renew Date_next           duration       
  <dttm>              <chr>     <dttm>              <drtn>         
1 2019-04-18 15:05:10 NEW       2019-04-18 15:07:52      2.700 mins
2 2019-04-18 15:07:52 NEW       2019-05-08 21:10:08  29162.267 mins
3 2019-05-08 21:10:08 NEW       2020-01-14 21:08:08 361438.000 mins
4 2020-01-14 21:08:08 NEW       2020-01-18 21:14:30   5766.367 mins
5 2020-01-18 21:14:30 NEW       2020-01-21 16:08:37   4014.117 mins
6 2020-01-21 16:08:37 NEW       2020-02-26 21:13:38  52145.017 mins
7 2020-02-26 21:13:38 NEW       NA                          NA mins
1 голос
/ 11 марта 2020

Опция, использующая data.table:

DT[, Date := as.POSIXct(Date, format="%Y-%m-%d %T")][
    New_Renew=="NEW", mean(diff(Date))]

данные:

library(data.table)
DT <- fread("Date,New_Renew
2019-01-10 22:11:16,Renewing
2019-02-23 00:21:48,Renewing
2019-03-05 05:26:17,Renewing
2019-04-18 15:05:10,     NEW
2019-04-18 15:07:52,     NEW
2019-04-26 11:32:25,Renewing
2019-05-03 14:15:25,Renewing
2019-05-08 21:10:08,     NEW
2019-05-16 13:35:57,Renewing
2019-05-24 13:18:23,Renewing
2019-06-01 12:42:21,Renewing
2019-06-17 18:08:09,Renewing
2019-06-26 13:40:29,Renewing
2019-12-13 17:57:43,Renewing
2020-01-03 11:49:14,Renewing
2020-01-11 11:46:51,Renewing
2020-01-14 21:08:08,     NEW
2020-01-18 21:14:30,     NEW
2020-01-21 16:08:37,     NEW
2020-01-28 11:41:44,Renewing
2020-01-30 13:34:21,Renewing
2020-02-03 13:29:37,Renewing
2020-02-18 17:15:52,Renewing
2020-02-20 13:37:52,Renewing
2020-02-24 12:55:25,Renewing
2020-02-26 21:13:38,     NEW
2020-03-04 13:23:41,Renewing
2020-03-09 16:48:36,Renewing")
1 голос
/ 10 марта 2020

Сначала создайте минимальный воспроизводимый пример

DT <- read.table(text = 'Date, New_Renew
 2019-01-10 22:11:16,Renewing
 2019-02-23 00:21:48,Renewing
 2019-03-05 05:26:17,Renewing
 2019-04-18 15:05:10,NEW
 2019-04-18 15:07:52,NEW
 2019-04-26 11:32:25,Renewing
 2019-05-03 14:15:25,Renewing
 2019-05-08 21:10:08,NEW
 2019-05-16 13:35:57,Renewing
 2019-05-24 13:18:23,Renewing
 2019-06-01 12:42:21,Renewing
 2019-06-17 18:08:09,Renewing
 2019-06-26 13:40:29,Renewing
 2019-12-13 17:57:43,Renewing
 2020-01-03 11:49:14,Renewing
 2020-01-11 11:46:51,Renewing
 2020-01-14 21:08:08,NEW
 2020-01-18 21:14:30,NEW
 2020-01-21 16:08:37,NEW
 2020-01-28 11:41:44,Renewing
 2020-01-30 13:34:21,Renewing
 2020-02-03 13:29:37,Renewing
 2020-02-18 17:15:52,Renewing
 2020-02-20 13:37:52,Renewing
 2020-02-24 12:55:25,Renewing
 2020-02-26 21:13:38,NEW
 2020-03-04 13:23:41,Renewing
 2020-03-09 16:48:36,Renewing', 
                 sep = ',', 
                 header = T)

Затем мы будем использовать xts для удобного вычисления дат. Функция for l oop является прямой, хранит первое обновление и вычитает первое новое из

library(data.table)
library(xts)
library(lubridate)
library(tbl2xts)

df <- xts(DT, order.by = ymd_hms(DT$Date))

new_items <- which(DT$New_Renew=="NEW")

dif <- DT

dif$difference <- NA

renewal <- 0

for (i in 1:nrow(df)){

  if (df[i,2]=='Renewing' & renewal == 0){
    renewal <- i
  } else if (df[i,2]=='Renewing' & renewal != 0){
    next
  } else if (df[i, 2]=='NEW' & renewal != 0) {
    dif[i, 'difference'] <- index(df[i, 2]) - index(df[renewal, 2])
    renewal <- i
  } else {
    dif[i, 'difference'] <- index(df[i, 2]) - index(df[renewal, 2])
    renewal <- 0
  }

}

mean_diff <- mean(dif$difference, na.rm = T)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...