我想生成一个边际均相等的随机列联表。

最简单的示例是拥有表:

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


所以sum(r_i) = sum(c_j) =9。我想找到所有符合此条件的列联表,然后能够分析该组表的某些功能。

有没有一种简单的方法可以在R中生成这些表?

最佳答案

您的问题并不完全准确。生成随机列联表很容易。查找所有符合这些条件的列联表可能会比较困难,因为表的概率高度不一致,并且需要非常大的样本才能确保全部拥有。 (有人给出了基于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提供了一种计算表数量的方法;所有等于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()包中的partitions函数开始的,该函数列举了将整数N划分为n组件的所有方式: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,一个合理的结果...)?

08-24 15:20