0

毎日出現する新規ユーザーの数と、ユーザーが 0 日目 (100%)、1 日目、2 日目などに再出現する可能性に基づいて、単純なコホートベースのユーザー維持モデルを作成しています。毎日アクティブなユーザーの数を知っています。私はこれをベクトル化しようとしていて、正しい混乱に陥っています。これがおもちゃのモックアップです。

rvec <- c(1, .8, .4);   #retention for day 0, 1,2 (day 0 = 100%, and so forth)
newvec <- c(10, 10, 10); #new joiners for day 0, 1, 2  (might be different)
playernumbers <- matrix(0, nrow = 3, ncol = 3);

# I want to fill matrix playernumbers  such that sum of each row gives 
# the total playernumbers on day rownumber-1
# here is a brute force method  (could be simplified via a loop or two)
# but what I am puzzled about is whether there is a way to fully vectorise it    
playernumbers[1,1] <- rvec[1] * newvec[1];
playernumbers[2,1] <- rvec[2] * newvec[1];
playernumbers[3,1] <- rvec[3] * newvec[1];
playernumbers[2,2] <- rvec[1] * newvec[2];
playernumbers[3,2] <- rvec[2] * newvec[2];
playernumbers[3,3] <- rvec[1] * newvec[3];
playernumbers

これを完全にベクトル化する方法がわかりません。各列番号を連続して使用して、(a) 更新する行 (列番号: nrows)、および (b) どの newvec インデックス値を乗算するかを示すために、列ごとにそれを行う方法を確認できます。しかし、ループがより明確であるため、これを行う価値があるかどうかはわかりません。しかし、私が見逃している完全にベクトル化されたフォームはありますか? ありがとう!

4

1 に答える 1

3

奇妙なインデックス作成ロジックを主張しない場合は、単純に外積を計算できます。

outer(rvec, newvec)
#     [,1] [,2] [,3]
#[1,]   10   10   10
#[2,]    8    8    8
#[3,]    4    4    4

外積では、ベクトル 1 の 2 番目の要素とベクトル 2 の 2 番目の要素の積が [2,2] に配置されます。[3,2] に配置します。なんで?

あなたの結果:

playernumbers
#     [,1] [,2] [,3]
#[1,]   10    0    0
#[2,]    8   10    0
#[3,]    4    8   10

編集:

これはあなたのループと同じことをするはずです:

rvec <- c(1, .8, .4)   
newvec <- c(10, 20, 30)

tmp <- outer(rvec, newvec)
tmp <- tmp[, ncol(tmp):1]
tmp[lower.tri(tmp)] <- 0
tmp <- tmp[, ncol(tmp):1]
res <- tmp*0
res[lower.tri(res, diag=TRUE)] <- tmp[tmp!=0]
#     [,1] [,2] [,3]
#[1,]   10    0    0
#[2,]    8   20    0
#[3,]    4   16   30

rowSums(res)
#[1] 10 28 50
于 2014-05-28T10:56:52.743 に答える