从列联表中抽样

时间:2011-06-16 17:56:44

标签: r sample contingency

我已经管理了以下代码,编写了一个从列联表中采样的函数 - 与单元格中的频率成比例。

它使用expand.grid然后使用table返回原始大小表。只要样本量足够大以至于某些类别不会完全丢失,这样就可以正常工作。否则,table命令返回一个尺寸小于原始尺寸的表。

FunSample<- function(Full, n) {
  Frame <- expand.grid(lapply(dim(Full), seq))
  table(Frame[sample(1:nrow(Frame), n, prob = Full, replace = TRUE), ])
}
Full<-array(c(1,2,3,4), dim=c(2,2,2))
FunSample(Full, 100) # OK
FunSample(Full, 1) # not OK, I want it to still have dim=c(2,2,2)!

我的大脑已停止工作,我知道必须进行一些小调整才能让它重回正轨!?

3 个答案:

答案 0 :(得分:3)

如果您不希望table()“删除”缺少的组合,则需要强制Frame的列成为因素:

FunSample <- function(Full, n) {
  Frame <- as.data.frame( lapply( expand.grid(lapply(dim(Full), seq)), factor) )  
  table( Frame[sample(1:nrow(Frame), n, prob = Full, replace = TRUE), ])
}   

> dim( FunSample(Full, 1))
[1] 2 2 2
> dim( FunSample(Full, 100))
[1] 2 2 2

答案 1 :(得分:3)

交叉表也是多项分布,因此您可以使用rmultinom并重置输出上的维度。这应该会大大提高性能并减少您需要维护的代码。

> X <- rmultinom(1, 500, Full)
> dim(X) <- dim(Full)
> X
, , 1

     [,1] [,2]
[1,]   18   92
[2,]   45   92

, , 2

     [,1] [,2]
[1,]   28   72
[2,]   49  104

> X2 <-rmultinom(1, 4, Full)
> dim(X2) <- dim(Full)
> X2
, , 1

     [,1] [,2]
[1,]    0    1
[2,]    0    0

, , 2

     [,1] [,2]
[1,]    0    1
[2,]    1    1

答案 2 :(得分:1)

您可以使用tabulate代替table;它适用于整数值向量,就像你在这里一样。您也可以直接使用array将输出转换为数组,就像创建原始数据一样。

FunSample<- function(Full, n) {
  samp <- sample(1:length(Full), n, prob = Full, replace = TRUE)
  array(tabulate(samp), dim=dim(Full))
}