0

我正在尝试为“粘性”定义一个函数 - 一个衡量用户参与度的业务分析指标 - 我的函数正在返回一个填充有意外数据的数据框。

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

UPDATE 工作功能(使用 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) 
}
4

1 回答 1

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

鉴于您对DAUand的描述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
于 2012-05-11T20:19:51.627 回答