根据单元格值从矩阵行中采样单元格
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
中选择一个从 id2
到 id10
的单元格。最有可能的选择是 id3
因为它的值 0.7
是该行中最高的。
我需要一个名为 result
的向量来存储我选择后每一行的选择。我目前的计划是:
- 跨行求和并将结果存储为向量
denom
- 为每一行生成一个介于 0 和此总和之间的随机统一变量
- 如果取值在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
您可以使用 apply
和 sample
从每一行中随机选择一个元素。我们创建一个包装 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 创建
一个 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
中选择一个从 id2
到 id10
的单元格。最有可能的选择是 id3
因为它的值 0.7
是该行中最高的。
我需要一个名为 result
的向量来存储我选择后每一行的选择。我目前的计划是:
- 跨行求和并将结果存储为向量
denom
- 为每一行生成一个介于 0 和此总和之间的随机统一变量
- 如果取值在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
您可以使用 apply
和 sample
从每一行中随机选择一个元素。我们创建一个包装 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 创建