生成随机列联表以检查元素

时间:2014-11-10 17:24:52

标签: r

我想生成一个随机列联表,边缘都相等。

最简单的例子就是拥有表格:

3   3   3   | 9
3   3   3   | 9
3   3   3   | 9
_   _   _ 
9   9   9   

所以sum(r_i) = sum(c_j) =9。我想找到符合这个标准的所有列联表,然后能够分析这组表的一些功能。

是否有一种“简单”的方式在R中生成这些表?

2 个答案:

答案 0 :(得分:5)

你的问题并不完全准确。生成随机列联表很容易。查找符合这些条件的所有列联表可能更难,因为表的概率非常不均匀,需要一个非常大的样本以确保您拥有所有这些表。 (有人给出了基于partitions包的确定性枚举解决方案的开头,但似乎已经删除了他们的答案......)r2dtable包中的stats(核心包样本随机表:

仅生成1个样本(结果以列表形式返回):

 set.seed(101)
 r2dtable(n=1,r=c(9,9,9),c=c(9,9,9))[[1]]
 ##      [,1] [,2] [,3]
 ## [1,]    4    3    2
 ## [2,]    2    4    3
 ## [3,]    3    2    4

你的榜样有多大?

 set.seed(102)
 tList <- r2dtable(n=50000,r=c(9,9,9),c=c(9,9,9))

将结果转换为字符串以便于比较:

 vals <- sapply(tList,function(x) paste(c(x),collapse=""))

有多少人?

 length(unique(vals))  ## 1018

更新:更大的样本(n = 500000)提供了1276个唯一表格。这似乎在对称的基础上更合理,但可能不完整 - 基于对数频率分布,可能还有一个更长的尾巴我还没有被抓住。

实际上有:this web page提供了一种计算表数的方法;所有边距均为1540,等于9。

对数频率分布:

plot(log10(rev(sort(table(vals)))),type="l")

enter image description here

最常见的表:

 head(rev(sort(table(vals))))
 ## vals
 ## 333333333 342324333 333324342 333342324 423333243 234333432 
 ##       996       626       626       605       596       592

(为了额外的功劳,我应该尝试折叠对称案例。)

全部平等的可能性:

 mean(vals=="333333333") ## 0.1992

确定性方法(我希望所有者将恢复)从compositions()包中的partitions函数开始,该函数枚举了将整数N分区为{{n的所有方法。 1}} components:compositions(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))

只有252好吗?也许我们需要允许这些结果的所有排列(这将允许252 * 6 = 1512,一个看似合理的结果......)?

答案 1 :(得分:1)

这可能是对这个问题的疯狂回答,这是一个疯狂的(也是不完整的)答案。但是,它与您的预期结果有关,也是数独的。这很有趣。

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

基本上,数独谜题是您正在寻找的特定情况。这也增加了约束,即每行和每列不仅具有相同的边缘,而且具有完全相同的元素组合。这个软件包只能实现9x9,16x16或25x25的谜题,但您可以查看源代码,了解它们如何生成谜题,并可能从那里构建更通用的解决方案。