2011-06-16 45 views
2

我已經管理了下面的代碼,寫了一個函數從應急表中抽樣 - 與細胞中的頻率成正比。從應急表中抽樣

它使用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)! 

我的大腦已經停止工作,我知道它必須做一些小調整才能讓它回到正軌!?

回答

2

交叉表也是一個多項分佈,所以你可以使用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 
+0

謝謝尼爾,這是一個美麗而優雅的解決方案,我已經改變了你的答案! – maja 2015-05-21 11:21:28

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

你可以使用tabulate代替table;它在整數值向量上工作,就像你在這裏一樣。您也可以直接使用array將輸出獲取到數組中,就像您創建原始數據時一樣。

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