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

R 按客户id计算购买日期的平均差异,r,R,我想知道如何使用R来计算下面的值 假设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

我想知道如何使用R来计算下面的值

  • 假设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    |
    
  • 我想算出客户平均回购间隔时间

  • 计算结果如下所示:

    | 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            |
    
  • 输出将是所有客户的总平均值——因此:60天=(客户1的平均值为30+客户2的平均值为90)/2个客户

  • 我假设您已将CSV读入名为
    df
    的数据框中,并且我已使用重命名变量,因为名称中有空格的变量,这导致许多变量使用snake case或变量命名约定

    下面是一个基本的R解决方案:

    mean(sapply(by(df$purchase_date, df$customer_id, diff), mean), na.rm=TRUE)
    
    [1] 60.75
    
    您可能会注意到,我们得到的是
    60.75
    ,而不是您预期的60。这是因为客户1的购买间隔为31天(1月至2月1日为31天),而客户2的购买间隔也类似——一个月内并不总是30天

    解释
    by()
    函数通过分组将另一个函数应用于数据。这里,我们通过
    df$customer\u id
    的唯一值将
    diff()
    应用于
    df$purchase\u date
    。这本身将产生以下输出:

    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中)。

    这里是另一个使用
    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))
    
    或使用
    数据。表

    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
    
    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))
    

    你能给我们提供你的数据帧的代码吗?您可以使用
    dput()
    函数获得它。这太棒了,谢谢。出于某种原因,我在by(…)函数调用中收到一个错误:`` as.character.factor(x)中的错误:格式错误的因子```代码:``基本上是`` as.character.factor(x):格式错误的因子``中的错误。试图更新我的评论,但格式错误。。。haI认为,只有通过拥有您的数据,才能重现此错误,并因此修复/解决此错误。如果将
    dput(orders)
    的输出添加到问题中,可能会有所帮助。作为将来的参考,如果你一开始就这样做,你通常会得到更好的答案(这就是为什么芭芭拉会留下这样的评论)。谢谢。对不起,我对R还是新手-我从这个帖子中学到了很多。通过将DF中的字段转换为日期字段,我使它一切正常。df$购买日期
    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))