我想生成一个边际均相等的随机列联表。
最简单的示例是拥有表:
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,一个合理的结果...)?