2014-04-24 25 views
1

我需要在每個地層繪製一個分層樣本,其觀測值爲n,但有些地層的觀測值比n少。如果某一層的觀測結果太少(例如,觀測值爲k<n),那麼我想要從該層中抽取所有的觀測值k部分地層太小時分層樣本

require(sampling) 

n <- 10 
geo_ID <- c(rep(1, times = 20), rep(2, times = 20), rep(c(1, 2, 3, 4), times = 5)) 
    set.seed(42) 
V1 <- rnorm(60, 0, 1) 
V2 <- rnorm(60, 2, 1) 

DF <- data.frame(geo_ID = geo_ID, V1 = V1, V2 = V2) 
    #Sort as explained in ?strata help file 
DF <- DF[order(DF[, "geo_ID"]), ] 

strata(DF, stratanames = "geo_ID", size = c(n, n, n, n), method = "srswor") 

如果我使用不放回抽樣如上,我(可以理解)得到錯誤:

Error in strata(DF, stratanames = "geo_ID", size = c(10, 10, 10, 10), : 
    not enough obervations in the stratum 

採樣與更換避免錯誤,method = "srswr",但是這不是理想的,因爲它有時會得出重複的這些地層足夠大,只能有獨特的樣品吸取。

注意:這裏有類似的問題,但它沒有真正回答。另外我認爲這個問題更一般。 (Stratified sampling - not enough observations)對於相關問題的答案通常並不實用,因爲它們要求:(i)與分層大小成比例的樣本大小(而我需要一個固定數量)或(ii)手動編程分層分層隨着地層數量的增加,這是不可行的。

回答

3

這並不回答你的問題,關於如何使用「採樣」軟件包做到這一點,但我寫了a function called stratified,這將爲你做到這一點。

如果你有註明「DevTools」安裝,您可以加載它是這樣的:

library(devtools) 
source_gist(6424112) 

否則,只是功能的代碼主旨複製到您的會話和樂趣。


用法很簡單:

set.seed(1) ## So you can reproduce this 
stratified(DF, group = "geo_ID", size = 10) 
# Some groups 
# ---3, 4--- 
# contain fewer observations than desired number of samples. 
# All observations have been returned from those groups. 
# geo_ID   V1  V2 
# 7  1 1.51152200 2.3358481 
# 9  1 2.01842371 2.9207286 
# 14  1 -0.27878877 1.0464766 
# 20  1 1.32011335 0.9002191 
# 5  1 0.40426832 1.2727079 
# :::SNIP::: 
# 43  3 0.75816324 0.9967914 
# 47  3 -0.81139318 1.5777441 
# 55  3 0.08976065 0.3389009 
# 51  3 0.32192527 1.9749074 
# 48  4 1.44410126 1.8776498 
# 44  4 -0.72670483 3.8484819 
# 60  4 0.28488295 2.1372562 
# 52  4 -0.78383894 2.1080727 
# 56  4 0.27655075 1.6176663 

有一些 「有趣」 的功能,如子集化的功能本身的階層:

## Selects only "geo_ID" values equal to 1 or 4 
stratified(DF, group = "geo_ID", size = 10, select = list(geo_ID = c(1, 4))) 

...走按比例抽樣:

## Just set the size argument to a value less than 1 
stratified(DF, group = "geo_ID", size = .1) 

...並使用多個列作爲您的組。 Gist上的評論包括一些可以嘗試的例子。

+0

謝謝!一個問題,在我的真實數據中,我有多個地理標識字段,一些數字和一些字符。上面的函數適用於數字(城鎮ID),但是當我在字符字段(城鎮名稱)上運行它時,我得到以下響應:'if(length(x)== 1L && is.numeric(x )&& x> = 1){:缺少TRUE/FALSE所需的值。雖然不知道沒有數據可能是不可能的,但是自從您編寫函數後,您可能會有線索。 –

+0

@DTRM,對不起。我已經離開了幾天。我會試着看看我是否可以重新創建你的錯誤。否則,如果您有一些重新創建錯誤的示例數據,請更新您的問題並在此處留言。 – A5C1D2H2I1M1N2O1R2T1

+0

@AHandcartAndMohair Gist鏈接目前被破壞:https://gist.github.com/mrdwab/6424112 – coip