按客户ID计算购买日期的平均差异

时间:2017-11-17 12:30:02

标签: r

想知道如何使用R来计算以下内容。

  1. 假设CSV包含以下购买数据:

    | Customer ID  | Purchase Date | 
    | 1            | 01/01/2017    |
    | 2            | 01/01/2017    |
    | 3            | 01/01/2017    |
    | 4            | 01/01/2017    |
    | 1            | 02/01/2017    |
    | 2            | 03/01/2017    |
    | 2            | 07/01/2017    |
    
  2. 我想弄清楚客户回购之间的平均时间。

  3. 数学将如下所示:

    | Customer ID  | AVG repurchase | 
    | 1            | 30 days        | = (02/01 - 01/01 / 1 order
    | 2            | 90 days        | = ( (03/01 - 01/01) + (07 - 3/1) ) /2 orders
    | 3            | n/a            |
    | 4            | n/a            |
    
    1. 输出将是客户的总平均值 - 因此:60天=(客户1平均为30,客户2平均为90平方英尺)/ 2位客户。

2 个答案:

答案 0 :(得分:1)

我们假设您已将CSV读入名为df的数据框,并且我已使用snake case重命名了您的变量,因为名称中包含空格的变量{{ 3}},导致许多人使用蛇案例或can be inconvenient变量命名约定。

以下是基础R解决方案:

mean(sapply(by(df$purchase_date, df$customer_id, diff), mean), na.rm=TRUE)

[1] 60.75

您可能会注意到我们得到60.75而不是您预期的60。这是因为客户1的购买之间有31天(1月份为31天,直到2月1日),对于客户2的购买也是如此 - 一个月内并不总是有30天。

解释

by(df$purchase_date, df$customer_id, diff)

by()函数通过分组将另一个函数应用于数据。在此,我们通过diff()的唯一值将df$purchase_date应用于df$customer_id。这将导致以下输出:

df$customer_id: 1
Time difference of 31 days
----------------------------------------------------------- 
df$customer_id: 2
Time differences in days
[1]  59 122

然后我们使用

sapply(by(df$purchase_date, df$customer_id, diff), mean)

mean()应用于上一结果的元素。这为我们每个客户的平均回购时间提供了:

   1    2    3    4 
31.0 90.5  NaN  NaN

(我们看到客户3和4从未回购过)。最后,我们需要平均这些平均回购时间,这意味着我们还需要处理那些NaN值,因此我们使用:

mean(sapply(by(df$purchase_date, df$customer_id, diff), mean), na.rm=TRUE)

将平均之前的结果,忽略缺失值(在R camel case中)。

答案 1 :(得分:0)

这是dplyr + lubridate的另一种解决方案:

library(dplyr)
library(lubridate)

df %>%
  mutate(Purchase_Date = mdy(Purchase_Date)) %>%
  group_by(Customer_ID) %>%
  summarize(AVG_Repurchase = sum(difftime(Purchase_Date, 
                                          lag(Purchase_Date), units = "days"), 
                                 na.rm=TRUE)/(n()-1))

data.table

library(data.table)

setDT(df)[, Purchase_Date := mdy(Purchase_Date)]

df[, .(AVG_Repurchase = sum(difftime(Purchase_Date, 
                                     shift(Purchase_Date), units = "days"), 
                            na.rm=TRUE)/(.N-1)), by = "Customer_ID"]

<强>结果:

# A tibble: 4 x 2
  Customer_ID AVG_Repurchase
        <dbl>         <time>
1           1      31.0 days
2           2      90.5 days
3           3       NaN days
4           4       NaN days

   Customer_ID AVG_Repurchase
1:           1      31.0 days
2:           2      90.5 days
3:           3       NaN days
4:           4       NaN days

注意:

我首先将Purchase_Date转换为mmddyyyy格式,然后group_by Customer_ID。对于每个Customer_ID的最终结果,我计算了Purchase_Date与其滞后之间的天差的平均值。

数据:

df = structure(list(Customer_ID = c(1, 2, 3, 4, 1, 2, 2), Purchase_Date = c(" 01/01/2017", 
" 01/01/2017", " 01/01/2017", " 01/01/2017", " 02/01/2017", " 03/01/2017", 
" 07/01/2017")), .Names = c("Customer_ID", "Purchase_Date"), class = "data.frame", row.names = c(NA, 
-7L))