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_uniqueDAUのダミー値を使用して計算を外側に進めます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が、常に対応するベクトルから2番目のユーザー名をmau_unique取得し、その長さを取得します。そのため、常に1を取得しますset28。なぜあなたが2番目の要素を引き出そうとし続けるのか分かりません。


編集:

合成的に生成されたデータは問題ありません。これは、小さなスペースに大量のデータを作成するための良い方法です。ランダムシードを設定すると、全員が同じデータを操作できるようになります。

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
于 2012-05-11T20:19:51.627 に答える