我想生成一个随机列联表,边缘都相等.
最简单的例子是拥有该表:
3 3 3 | 9
3 3 3 | 9
3 3 3 | 9
_ _ _
9 9 9
Run Code Online (Sandbox Code Playgroud)
所以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
Run Code Online (Sandbox Code Playgroud)
你的榜样有多大可能?
set.seed(102)
tList <- r2dtable(n=50000,r=c(9,9,9),c=c(9,9,9))
Run Code Online (Sandbox Code Playgroud)
将结果转换为字符串以便于比较:
vals <- sapply(tList,function(x) paste(c(x),collapse=""))
Run Code Online (Sandbox Code Playgroud)
那里有多少?
length(unique(vals)) ## 1018
Run Code Online (Sandbox Code Playgroud)
更新:更大的样本(n = 500000)给出了1276个唯一表.这在对称性的基础上似乎更合理,但可能并不完整 - 基于对数频率分布,可能还有更长的尾巴,我还没有抓到.
实际上有:这个网页提供了一种计算表数的方法; 所有边距均为1540,等于9.
对数频率分布:
plot(log10(rev(sort(table(vals)))),type="l")
Run Code Online (Sandbox Code Playgroud)

最常见的表格:
head(rev(sort(table(vals))))
## vals
## 333333333 342324333 333324342 333342324 423333243 234333432
## 996 626 626 605 596 592
Run Code Online (Sandbox Code Playgroud)
(为了额外的功劳,我应该尝试崩溃对称案例.)
全部平等的可能性:
mean(vals=="333333333") ## 0.1992
Run Code Online (Sandbox Code Playgroud)
确定性方法(我希望所有人将恢复)与开始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))
Run Code Online (Sandbox Code Playgroud)
只有252好吗?也许我们需要允许这些结果的所有排列(这将允许252*6 = 1512,一个看似合理的结果......)?