R 生成随机列联表以检查元素
我想生成一个边距都相等的随机列联表 最简单的示例是有以下表格:R 生成随机列联表以检查元素,r,R,我想生成一个边距都相等的随机列联表 最简单的示例是有以下表格: 3 3 3 | 9 3 3 3 | 9 3 3 3 | 9 _ _ _ 9 9 9 所以sum(r_i)=sum(c_j)=9。我希望找到所有符合此标准的列联表,然后能够分析这组表的一些特性 有没有一种“简单”的方法可以在R中生成这些表格?这可能是对这个问题的疯狂回答,也是一个疯狂(也是不完整)的回答。但是,它与你的预期结果有关,也是数独。这很有趣 library("su
3 3 3 | 9
3 3 3 | 9
3 3 3 | 9
_ _ _
9 9 9
所以sum(r_i)=sum(c_j)=9
。我希望找到所有符合此标准的列联表,然后能够分析这组表的一些特性
有没有一种“简单”的方法可以在R中生成这些表格?这可能是对这个问题的疯狂回答,也是一个疯狂(也是不完整)的回答。但是,它与你的预期结果有关,也是数独。这很有趣
library("sudokuAlt")
g <- matrix(as.numeric(makeGame(3,0)), nrow = 9)
colSums(g)
# [1] 45 45 45 45 45 45 45 45 45
rowSums(g)
# [1] 45 45 45 45 45 45 45 45 45
库(“sudokuAlt”)
你的问题不完全准确。生成随机列联表很容易。找到所有符合这些标准的列联表可能会更加困难,因为表的概率是高度不均匀的,并且需要非常大的样本才能确保您拥有所有的列联表。(有人给出了一个基于分区
包的确定性枚举解决方案的开始,但似乎已经删除了他们的答案…)
仅生成1个样本(结果作为列表返回):
你的例子有多大可能
set.seed(102)
tList <- r2dtable(n=50000,r=c(9,9,9),c=c(9,9,9))
更新:一个更大的样本(n=500000)给出了1276个独特的表。从对称性的角度来看,这似乎更合理,但可能不完全——根据对数频率分布,可能还有一条更长的尾巴我还没有抓住
事实上有:给出了一种计算表数的方法;所有等于9的边距都有1540
对数频率分布:
plot(log10(rev(sort(table(vals)))),type="l")
最常见的表格:
head(rev(sort(table(vals))))
## vals
## 333333333 342324333 333324342 333342324 423333243 234333432
## 996 626 626 605 596 592
(为了获得额外的学分,我应该尝试折叠对称案例。)
全部相等的概率:
mean(vals=="333333333") ## 0.1992
确定性方法(我希望所有者能够恢复)从分区
包中的compositions()
函数开始,该函数列举了将整数N
分区为N
组件的所有方法:组合(9,3)
给出3个总和为9的非负整数的所有集合,表示列联矩阵中所有可能的行/列
我仍在考虑如何使用这些原材料,并将它们合并到枚举表中:其中必须至少有1276个,因此不仅仅是单个成分的所有排列(这只会给出3!*55=330)
这只是一个开始,但实际上不起作用:
library("partitions")
cc <- compositions(9,3)
too.many <- combn(split(cc,col(cc)),3,
FUN=function(x) do.call(cbind,x),
simplify=FALSE) ## 26235
ok <- sapply(too.many,function(x) all(rowSums(x)==9))
库(“分区”)
很好,反应很彻底。我最终选择了r2dtable路线,因为我实际上是在处理有3500万个可能矩阵的矩阵。这种方法很好,足以让我获得所需的信息。谢谢
head(rev(sort(table(vals))))
## vals
## 333333333 342324333 333324342 333342324 423333243 234333432
## 996 626 626 605 596 592
mean(vals=="333333333") ## 0.1992
library("partitions")
cc <- compositions(9,3)
too.many <- combn(split(cc,col(cc)),3,
FUN=function(x) do.call(cbind,x),
simplify=FALSE) ## 26235
ok <- sapply(too.many,function(x) all(rowSums(x)==9))