计算 R 中的简单保留
calculating simple retention in R
对于数据集 test
,我的 objective 是找出有多少独立用户从一个时期转移到下一个时期。
> 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。在第二个时期有三个独立用户,其中两个在第三个时期活跃,所以留存率为 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")
这不是很优雅,但似乎可行。假设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% 创建了第一个参数的每个元素是否在第二个参数中的逻辑。取平均值给我们比例。
这个怎么样?首先按时段拆分用户,然后编写一个函数计算任意两个时段之间的比例结转,然后循环遍历拆分列表 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
这是使用 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))
这个returns:
period retention
<dbl> <dbl>
1 1 NA
2 2 0.5000000
3 3 0.6666667
4 4 0.5000000
对于数据集 test
,我的 objective 是找出有多少独立用户从一个时期转移到下一个时期。
> 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。在第二个时期有三个独立用户,其中两个在第三个时期活跃,所以留存率为 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")
这不是很优雅,但似乎可行。假设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% 创建了第一个参数的每个元素是否在第二个参数中的逻辑。取平均值给我们比例。
这个怎么样?首先按时段拆分用户,然后编写一个函数计算任意两个时段之间的比例结转,然后循环遍历拆分列表 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
这是使用 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))
这个returns:
period retention
<dbl> <dbl>
1 1 NA
2 2 0.5000000
3 3 0.6666667
4 4 0.5000000