我正在创建一个简单的基于群组的用户保留模型,基于每天出现的新用户数量,以及用户在第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索引值。但我不确定这是值得做的,因为对我而言,循环更清晰。但我错过了完全矢量化的形式吗?谢谢!
答案 0 :(得分:3)
如果你不坚持你的奇怪的索引逻辑,你可以简单地计算外部产品:
outer(rvec, newvec)
# [,1] [,2] [,3]
#[1,] 10 10 10
#[2,] 8 8 8
#[3,] 4 4 4
在外产物中,载体1的第二元素和载体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