有没有办法对这种加权的、抽样的排名操作进行矢量化?

Is there a way to vectorise this weighted, sampled ranking operation?

抱歉,如果这有点令人费解。我正在 运行 进行基于代理的模拟,并希望在每个时间步 'promote' n 个人。我有一个逻辑模型,对于每个人,它给我一个他们被提升的预测概率。我想随机 select n 个人,根据他们的晋升概率加权,进行晋升。

目前我运行这段代码:

test_frame <- data.frame(
  id = seq(1,10),
  promote_prob = sample(c(0.0000001, 0.5), 10, TRUE)
)

id_list <- data.frame(n = sample(test_frame$id, 
                                 nrow(test_frame), 
                                 prob = test_frame$promote_prob),
                      rank = seq(1, nrow(test_frame)))

test_frame %>%
  left_join(id_list, by = c("id" = "n")) %>%
  mutate(promote_flag = ifelse(rank < 3, 1, 0))

ID_list 根据提升概率对 table 中的所有行进行随机加权排名。但是连接操作使这个过程非常缓慢——这是迄今为止模拟中最慢的一步。有没有办法将这一系列步骤矢量化?我对此的实验并没有取得多大成果 - 例如:

test_frame %>%
  mutate(n = sample(seq(1:nrow(test_frame)), nrow(test_frame), FALSE, promote_prob)) %>%
  mutate(promote = ifelse(n < 3, 1, 0))

这应该有效:

set.seed(1)

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
test_frame <- data.frame(
  id = seq(1,10),
  promote_prob = sample(c(0.0000001, 0.5), 10, TRUE)
)

test_frame %>%
  mutate(promote = ifelse(id %in% sample(id, 2, replace=FALSE, promote_prob), 1,0))
#>    id promote_prob promote
#> 1   1        1e-07       0
#> 2   2        5e-01       1
#> 3   3        1e-07       0
#> 4   4        1e-07       0
#> 5   5        5e-01       0
#> 6   6        1e-07       0
#> 7   7        1e-07       0
#> 8   8        1e-07       0
#> 9   9        5e-01       1
#> 10 10        5e-01       0

reprex package (v2.0.1)

于 2022-04-26 创建

经过 5000 次迭代,观察值 2、5、9 和 10 被选中的概率大致相等,而其他的则根本没有被选中。重要的一点是 sample(id, 2, ...) 中的 2,它标识要提升的观察数。