我正在尝试为“粘性”定义一个函数 - 一个衡量用户参与度的业务分析指标 - 我的函数正在返回一个填充了意外数据的数据框。
stickiness <- function(tdata) {
require(plyr)
mau_unique <- dlply(.data = tdata,
.variables = "dt",
.fun = function(x){unique(x$username)})
dates_char <- names(mau_unique)
dates_vector <- as.Date(dates_char[28:(length(dates_char))],
format = "%Y-%m-%d")
output_df <- data.frame(dates_vector,
matrix(data = 0,
nrow = length(dates_char) - 27,
ncol = 3))
colnames(output_df) <- c("Date", "DAU", "MAU", "Stickiness")
for (i in 1:length(dates_vector)) {
dt <- dates_vector[i]
output_df[i, "DAU"] <- length(unlist(mau_unique[[as.character(dt)]][2]))
set28 <- unique(unlist(lapply(X = mau_unique[i:(i + 27)], FUN = "[[", 2)))
output_df[i, "MAU"] <- length(set28)
output_df[i, "Stickiness"] <- output_df[i, "DAU"] / output_df[i, "MAU"]
}
return(output_df)
}
返回以下内容:
Date DAU MAU Stickiness
1 2012-04-28 1 28 0.03571429
2 2012-04-29 1 28 0.03571429
3 2012-04-30 1 28 0.03571429
4 2012-05-01 1 28 0.03571429
5 2012-05-02 1 28 0.03571429
6 2012-05-03 1 28 0.03571429
7 2012-05-04 1 28 0.03571429
8 2012-05-05 1 28 0.03571429
9 2012-05-06 1 28 0.03571429
10 2012-05-07 1 28 0.03571429
我期待以下内容:
Date DAU MAU Stickiness
1 2012-04-28 25000 250000 0.10000000
... ... ... ... ...
10 2012-05-07 27371 284114 0.09633809
我怀疑问题与我正在评估的环境有关。
更新的样本数据:
> tdata
dt username
4236 2012-04-06 241343664
3091 2012-04-06 306001012
2936 2012-04-06 388682041
5790 2012-04-05 235612064
6763 2012-04-05 69650072
3392 2012-04-06 617142
7684 2012-04-05 189752749
3904 2012-04-06 255852653
7915 2012-04-05 182713266
6107 2012-04-05 187675644
更新工作功能(使用Brian Diggs的回答):
stickiness <- function(tdata) {
require(plyr)
mau_unique <- dlply(.data = tdata,
.variables = "dt",
.fun = function(x){unique(x$username)})
dates_char <- names(mau_unique)
dates_vector <- as.Date(dates_char[28:(length(dates_char))],
format = "%Y-%m-%d")
output_df <- data.frame(dates_vector,
matrix(data = 0,
nrow = length(dates_char) - 27,
ncol = 3))
colnames(output_df) <- c("Date", "DAU", "MAU", "Stickiness")
for (i in 1:length(dates_vector)) {
dt <- dates_vector[i]
output_df[i, "DAU"] <- length((mau_unique[[as.character(dt)]])
set28 <- unique(do.call(c, mau_unique[i:(i + 27)]))
output_df[i, "MAU"] <- length(set28)
output_df[i, "Stickiness"] <- output_df[i, "DAU"] / output_df[i, "MAU"]
}
return(output_df)
}
答案 0 :(得分:4)
感谢您添加一些示例数据,但它仍然无法真正重现,因为该函数假定数据跨越至少28天(或者更确切地说,至少28个唯一日期)。
问题,就像我能说的那样,在你的for循环中。使用您的示例数据
> mau_unique
$`2012-04-05`
[1] 235612064 69650072 189752749 182713266 187675644
$`2012-04-06`
[1] 241343664 306001012 388682041 617142 255852653
attr(,"split_type")
[1] "data.frame"
attr(,"split_labels")
dt
1 2012-04-05
2 2012-04-06
所以在计算DAU
时,您从mau_unique
中提取相应的元素。使用DAU
的虚拟值计算dt
向外工作:
> dt <- as.Date("2012-04-05")
> dt
[1] "2012-04-05"
> as.character(dt)
[1] "2012-04-05"
> mau_unique[[as.character(dt)]]
[1] 235612064 69650072 189752749 182713266 187675644
> mau_unique[[as.character(dt)]][2]
[1] 69650072
> unlist(mau_unique[[as.character(dt)]][2])
[1] 69650072
> length(unlist(mau_unique[[as.character(dt)]][2]))
[1] 1
我不知道应该如何计算DAU
,但是你总是从mau_unique
中的相应向量中获取第二个用户名,并取长度,这就是为什么你总是得到1。你正在为set28
做类似的事情;我不知道你为什么一直试图把第二个元素拉出来。
编辑:
综合生成的数据很好。这是在一个小空间中创建大量数据的好方法,设置随机种子将允许每个人使用相同的数据。
set.seed(1234)
tdata <- data.frame(dt = sample(seq(as.Date("2012-04-01"),
as.Date("2012-04-30"),
by = "day"),
size = 10000,
replace = TRUE),
username = sample(10000:10200,
10000,
replace = TRUE))
鉴于你对DAU
和MAU
的描述,我认为你的for循环应该是:(函数的其余部分没有改变)
for (i in 1:length(dates_vector)) {
dt <- dates_vector[i]
output_df[i, "DAU"] <- length(mau_unique[[as.character(dt)]])
output_df[i, "MAU"] <- length(unique(unlist(mau_unique[i:(i+27)])))
output_df[i, "Stickiness"] <- output_df[i, "DAU"] / output_df[i, "MAU"]
}
鉴于此,你的粘性是:
> stickiness(tdata)
Date DAU MAU Stickiness
1 2012-04-28 156 201 0.7761194
2 2012-04-29 168 201 0.8358209
3 2012-04-30 152 201 0.7562189