【问题标题】:Calculating average number of customer purchases since the year joined in R计算自加入 R 以来的平均客户购买次数
【发布时间】:2018-04-25 02:17:28
【问题描述】:

我在 R 中有以下数据框,它显示了 4 位客户在四年内每年的购买次数。 member_since 变量显示客户加入公司的年份。

id<-c(1,2,3,4)
member_since<-c(2014,2016,2015,2014)
X2014<-c(2,0,0,3)
X2015<-c(3,0,4,2)
X2016<-c(3,2,3,4)
X2017<-c(2,3,6,0)
df<-data.frame(id,member_since,X2014,X2015,X2016,X2017)

 id    member_since X2014 X2015 X2016 X2017
 1         2014      2     3     3     2
 2         2016      0     0     2     3
 3         2015      0     4     3     6
 4         2014      3     2     4     0

现在我正在尝试创建一个新变量 mean_purchase 来计算每个客户从他/她加入的那一年开始的平均每年购买次数。这意味着例如对于customer 2,购买总数应除以 2,但对于 customer 4,购买总和应除以 4。

 id    member_since X2014 X2015 X2016 X2017 mean_purchase
 1         2014      2     3     3     2         2.5
 2         2016      0     0     2     3         2.5
 3         2015      0     4     3     6         4.33
 4         2014      3     2     4     0         2.25

非常感谢您对此的帮助。

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以使用apply

    df$mean_purchase <- apply(df[3:6], 1, function(x) round(sum(x)/sum(cumsum(x > 0) > 0), 2))
    df$mean_purchase
    #[1] 2.50 2.50 4.33 2.25
    

    或者使用rowCumsums 来自matrixStats

    library(matrixStats)
    rowSums(df[3:6])/rowSums(rowCumsums(+(df[3:6] > 0)) > 0)
    

    【讨论】:

      【解决方案2】:

      根据 akrun 的回答,如果您想包括客户加入该计划但在第一年没有购买任何东西的情况,请使用 mapply,这里是一个轻微的概括。

      mapply(function(x,y) round(mean(unlist(df[x,(3+y):6])),2), 
             1:nrow(df), df$member_since - 2014)
      # [1] 2.50 2.50 4.33 2.25
      

      【讨论】:

      • 好一个。很高兴注意到您在分析中考虑了member_since(正如 OP 所期望的那样)。
      【解决方案3】:

      apply 的不同解决方案

      df$mean_purchase <- apply(df[3:6], 1, function(x) mean(x[min(which(x != 0)):length(x)]))
      df$mean_purchase
      # [1] 2.500000 2.500000 4.333333 2.250000
      

      【讨论】:

      • 对不起,我最初误读了您的问题。我已经更改了我的代码,它现在可以满足您的期望。
      【解决方案4】:

      我们将不相关的零替换为NA(我建议您保持这种方式),然后我们使用rowMeans

      df[-(1:2)][t(apply(df[-(1:2)],1,cumsum))==0] <- NA
      df$mean_purchase <- rowMeans(df[-(1:2)],na.rm=T)
      
      #   id member_since X2014 X2015 X2016 X2017 mean_purchase
      # 1  1         2014     2     3     3     2      2.500000
      # 2  2         2016    NA    NA     2     3      2.500000
      # 3  3         2015    NA     4     3     6      4.333333
      # 4  4         2014     3     2     4     0      2.250000
      
      # If you really don't want to keep NAs :
      df[is.na(df)] <- 0 
      

      【讨论】:

        【解决方案5】:

        一个选项是使用tidyr::gatherdplyr::filter 来确保mean 仅计算member_since 之后的年份。实现可以是:

        library(tidyverse)
        
        df %>% gather(year, value, -id, -member_since) %>%
          filter(member_since <= as.numeric(gsub("^X(\\d+)","\\1",year))) %>%
          group_by(id) %>%
          summarise(mean = mean(value)) %>%
          right_join(df, by="id") %>%
          select(-mean, mean) %>% as.data.frame()
        
        #   id member_since X2014 X2015 X2016 X2017 mean
        # 1  1         2014     2     3     3     2 2.50
        # 2  2         2016     0     0     2     3 2.50
        # 3  3         2015     0     4     3     6 4.33
        # 4  4         2014     3     2     4     0 2.25
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-28
          • 2020-04-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多