【问题标题】:calculating simple retention in R计算R中的简单保留
【发布时间】:2017-05-19 20:46:23
【问题描述】:

对于数据集test,我的目标是逐个周期地找出有多少唯一用户从一个时期转移到下一个时期。

> test
   user_id period
1        1      1
2        5      1
3        1      1
4        3      1
5        4      1
6        2      2
7        3      2
8        2      2
9        3      2
10       1      2
11       5      3
12       5      3
13       2      3
14       1      3
15       4      3
16       5      4
17       5      4
18       5      4
19       4      4
20       3      4

例如,在第一阶段有四个唯一用户(1、3、4 和 5),其中两个在第二阶段处于活跃状态。因此,保留率为 0.5。在第二个时期有 3 个独立用户,其中两个在第三个时期是活跃的,因此保留率为 0.666,依此类推。如何找到在下一时期活跃的唯一用户的百分比?任何建议将不胜感激。

输出如下:

> output
  period retention
1      1        NA
2      2     0.500
3      3     0.666
4      4     0.500

test 数据:

> dput(test)
structure(list(user_id = c(1, 5, 1, 3, 4, 2, 3, 2, 3, 1, 5, 5, 
2, 1, 4, 5, 5, 5, 4, 3), period = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 
2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4)), .Names = c("user_id", "period"
), row.names = c(NA, -20L), class = "data.frame")

【问题讨论】:

    标签: r dplyr retention


    【解决方案1】:

    这个怎么样?先按时期分割用户,然后写一个函数计算任意两个时期之间的比例结转,然后用mapply在分割列表中循环。

    splt <- split(test$user_id, test$period)
    
    carryover <- function(x, y) {
        length(unique(intersect(x, y))) / length(unique(x))
    }
    mapply(carryover, splt[1:(length(splt) - 1)], splt[2:length(splt)])
    
            1         2         3 
    0.5000000 0.6666667 0.5000000 
    

    【讨论】:

      【解决方案2】:

      这是一个使用dplyr的尝试,虽然它也在summarise中使用了一些标准语法:

      test %>% 
      group_by(period) %>% 
      summarise(retention=length(intersect(user_id,test$user_id[test$period==(period+1)]))/n_distinct(user_id)) %>% 
      mutate(retention=lag(retention))
      

      这会返回:

      period retention
         <dbl>     <dbl>
      1      1        NA
      2      2 0.5000000
      3      3 0.6666667
      4      4 0.5000000
      

      【讨论】:

      • 计算唯一user_ids的长度不是更好吗?我认为如果一个用户在一段时间内出现两次,它仍然应该算作一个回访用户。
      • @giac_man 默认情况下,intersect 会删除所有重复项,因此无需添加 unique,因为该操作已包含在其中。
      • 啊,我明白了。谢谢
      • 我也可以问你为什么使用 period+1 然后应用函数滞后。你不能用 period -1 代替吗?
      • @giac_man 第 2 期的留存率是第 1 期和第 2 期的唯一用户数除以第 1 期的唯一用户数。如果按照您的描述进行操作,分子将是正确的,但您将除以第 2 期而不是第 1 期的唯一用户数,这不会给您想要的结果。
      【解决方案3】:

      这不是那么优雅,但它似乎工作。假设df是数据框:

      # make a list to hold unique IDS by 
      uniques = list()
      for(i in 1:max(df$period)){
        uniques[[i]] = unique(df$user_id[df$period == i])
      }
      
      # hold the retention rates
      retentions = rep(NA, times = max(df$period))
      
      for(j in 2:max(df$period)){
        retentions[j] = mean(uniques[[j-1]] %in% uniques[[j]])
      }
      

      基本上,%in% 创建了第一个参数的每个元素是否在第二个参数中的逻辑。取平均值就可以得到比例。

      【讨论】:

        猜你喜欢
        • 2020-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多