根据单元格值从矩阵行中采样单元格

sampling cells from matrix rows based on cell values

一个 10x10 矩阵包含 "likelihoods" 用于在抽奖期间在给定行中选择的任何单元格。

        id1 id2 id3 id4 id5 id6 id7 id8 id9 id10
id1     NA  0.5 0.7 0.5 0.5 0.4 0.4 0.4 0.4 0.4
id2     0.5 NA  0.5 0.5 0.5 0.4 0.4 0.4 0.4 0.4
id3     0.7 0.5 NA  0.5 0.5 0.4 0.4 0.4 0.4 0.4
id4     0.5 0.5 0.5 NA  0.5 0.4 0.4 0.4 0.4 0.4
id5     0.5 0.5 0.5 0.5 NA  0.4 0.4 0.4 0.4 0.4
id6     0.4 0.4 0.4 0.4 0.4 NA  0.5 0.7 0.5 0.5
id7     0.4 0.4 0.4 0.4 0.4 0.5 NA  0.5 0.5 0.5
id8     0.4 0.4 0.4 0.4 0.4 0.7 0.5 NA  0.5 0.5
id9     0.4 0.4 0.4 0.4 0.4 0.5 0.5 0.5 NA  0.5
id10    0.4 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 NA

每次抽奖都是按行进行的,单元格被选中的几率是该单元格的值除以给定行中所有单元格值的总和。例如,我需要在行 id1 中选择一个从 id2id10 的单元格。最有可能的选择是 id3 因为它的值 0.7 是该行中最高的。

我需要一个名为 result 的向量来存储我选择后每一行的选择。我目前的计划是:

  1. 跨行求和并将结果存储为向量 denom
  2. 为每一行生成一个介于 0 和此总和之间的随机统一变量
  3. 如果取值在0.0到0.5之间,则第1行选中的人为id2;如果0.51-1.20,被选中的人是id3...等等

这显然工作量太大了。在忽略对角线中的 NA 值的同时使用权重进行采样的更好方法是什么?

我想你需要的是 sample 函数 https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/sample

您可以使用 applysample 从每一行中随机选择一个元素。我们创建一个包装 sample 的自定义函数来处理对角线上的缺失值并使用正确的权重。一件方便的事情是,在使用 na.omit 删除缺失值后,生成的向量仍然有名称,因此我们可以使用相应的概率作为权重与 prob 参数对名称进行采样。

mat <- as.matrix(read.table(
text = "id1 id2 id3 id4 id5 id6 id7 id8 id9 id10
id1  NA  0.5 0.7 0.5 0.5 0.4 0.4 0.4 0.4 0.4
id2  0.5 NA  0.5 0.5 0.5 0.4 0.4 0.4 0.4 0.4
id3  0.7 0.5 NA  0.5 0.5 0.4 0.4 0.4 0.4 0.4
id4  0.5 0.5 0.5 NA  0.5 0.4 0.4 0.4 0.4 0.4
id5  0.5 0.5 0.5 0.5 NA  0.4 0.4 0.4 0.4 0.4
id6  0.4 0.4 0.4 0.4 0.4 NA  0.5 0.7 0.5 0.5
id7  0.4 0.4 0.4 0.4 0.4 0.5 NA  0.5 0.5 0.5
id8  0.4 0.4 0.4 0.4 0.4 0.7 0.5 NA  0.5 0.5
id9  0.4 0.4 0.4 0.4 0.4 0.5 0.5 0.5 NA  0.5
id10 0.4 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 NA"
))

foo <- function(row) {
  no_na <- na.omit(row)
  sample(x = names(no_na), size = 1, prob = no_na)
}

result <- apply(mat, 1, foo)
result
#>    id1    id2    id3    id4    id5    id6    id7    id8    id9   id10 
#>  "id2"  "id9"  "id4"  "id2"  "id3"  "id8"  "id8" "id10"  "id3"  "id7"

reprex package (v0.3.0)

于 2019-09-24 创建