【问题标题】:How to create a stratified sample by state in R如何在 R 中按状态创建分层样本
【发布时间】:2012-03-14 14:00:45
【问题描述】:

如何使用“采样”包在 R 中创建分层样本?我的数据集有 355,000 个观察值。该代码可以正常工作到最后一行。以下是我编写的代码,但我总是收到以下消息:“sort.list(y) 中的错误:'x' 对于 'sort.list' 必须是原子的,你在列表上调用了 'sort' 吗?”

请不要将我指向 Stackoverflow 上的旧消息。我研究了它们,但无法使用它们。谢谢。

## lpdata file has 355,000 observations
# Exclude Puerto Rico, Virgin Islands and Guam
sub.lpdata<-subset(lpdata,"STATE" != 'PR' | "STATE" != 'VI' | "STATE" != 'GU')

## Create a 10% sample, stratified by STATE
sort.lpdata<-sub.lpdata[order(sub.lpdata$STATE),]
tab.state<-data.frame(table(sort.lpdata$STATE))
size.strata<-as.vector(round(ceiling(tab.state$Freq)*0.1))

s<-strata(sort.lpdata,stratanames=sort.lpdata$STATE,size=size.strata,method="srswor")}

【问题讨论】:

  • 尝试用stratanames = "STATE"替换stratanames = sort.lpdata$STATE。

标签: r random-sample


【解决方案1】:

去年我不得不做类似的事情。如果这是你经常做的事情,你可能想要使用下面这样的函数。此函数可让您指定要从中采样的数据框的名称、哪个变量是 ID 变量、哪个是分层,以及是否要使用“set.seed”。您可以将该函数保存为“stratified.R”之类的内容,并在需要时加载它。见http://news.mrdwab.com/2011/05/20/stratified-random-sampling-in-r-from-a-data-frame/

stratified = function(df, group, size) {
  #  USE: * Specify your data frame and grouping variable (as column 
  #         number) as the first two arguments.
  #       * Decide on your sample size. For a sample proportional to the
  #         population, enter "size" as a decimal. For an equal number 
  #         of samples from each group, enter "size" as a whole number.
  #
  #  Example 1: Sample 10% of each group from a data frame named "z",
  #             where the grouping variable is the fourth variable, use:
  # 
  #                 > stratified(z, 4, .1)
  #
  #  Example 2: Sample 5 observations from each group from a data frame
  #             named "z"; grouping variable is the third variable:
  #
  #                 > stratified(z, 3, 5)
  #
  require(sampling)
  temp = df[order(df[group]),]
  if (size < 1) {
    size = ceiling(table(temp[group]) * size)
  } else if (size >= 1) {
    size = rep(size, times=length(table(temp[group])))
  }  
  strat = strata(temp, stratanames = names(temp[group]), 
                 size = size, method = "srswor")
  (dsample = getdata(temp, strat))
}

【讨论】:

  • 您好 mrdwab,我认为您的代码有问题:如果我(当然是其他人)指定大小 >= 1,则会引发错误。问题当然是 p 没有在代码中的任何地方定义...
  • @nanounanue,感谢您指出这一点。我想我只是建立在另一个答案的基础上,p 在工作区中,我也忘了在这个函数的副本中修复它。现在已修复(我希望!)。
【解决方案2】:

在不知道分层功能的情况下 - 一些编码可能会做想要的事情:

d <- expand.grid(id = 1:35000, stratum = letters[1:10])

p = 0.1

dsample <- data.frame()

system.time(
for(i in levels(d$stratum)) {
  dsub <- subset(d, d$stratum == i)
  B = ceiling(nrow(dsub) * p)
  dsub <- dsub[sample(1:nrow(dsub), B), ]
  dsample <- rbind(dsample, dsub) 
  }
)

# size per stratum in resulting df is 10 % of original size:
table(dsample$stratum)

HTH, 凯

ps:我的旧笔记本电脑上的 CPU 时间是 0.09!

【讨论】:

  • 很好的解决方案...但是采样包和分层函数的一个优点是其他采样算法可用....
  • 使用你的数据集,可以做到:size
  • 感谢您的解决方案。我会去的。
  • @dickoa 您的示例有效,但如果我使用实际数据时出现错误“sort.list(y) 中的错误:'x' 必须是 'sort.list' 的原子” 这是带有数据的代码示例:库(外国);汽车stat.berkeley.edu/classes/s133/data/…); 名称(汽车); p = 0.1; dsample
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
相关资源
最近更新 更多