完成半控制随机集的最佳 SAS PROC SURVEYSELECT 选项是什么?

What's the best SAS PROC SURVEYSELECT options for accomplishing a semi-controlled random set?

我正在使用的场景是创建一个接受数据集并生成随机分层样本的宏,分层应该由 STATE 列进行,该列也需要相等的表示总数(如果可能)创建随机样本。

所需样本的大小有一些我们必须遵守的既定规则:

  1. 如果总数据集大小 <= 50,则让样本大小 = 整个数据集
  2. 否则,如果总数据集大小在 51 到 500 之间,则让样本大小 = 50
  3. 否则,如果总数据集大小在 501 到 999 之间,则让样本大小 = 总数据集大小 (n*.10) 的 10%,因为 n = 总数据集大小。
  4. 否则,如果总数据集大小 > 999,则让样本大小 = 100

SAMPLESIZE 当前在代码中定义为:

    /*sets sample size in accordance to standards*/
%if &num>=0 and &num<=50 %then %let samplesize=&num;
    %else %if &num<501 %then %let samplesize=50;
    %else %if &num<1000 %then %let samplesize=%sysevalf((&num*.10),ceil);
    %else %let samplesize=100;

我用于测试的数据集共有 550 条记录(因此需要的样本量为 55),每个州的总数如下:

  1. IN = 100
  2. KY=217
  3. MO = 189
  4. OH = 8
  5. WI = 36

当每个州都具有满足样本量所需的最小数量时,为 SURVEYSELECT 应用 STRATA 选项效果很好。在这种情况下,每个 STRATA 的 SAMPLESIZE 将为 11

可以看到这里的OH STRATUM不满足SAMPLESIZE的最低要求,因为数据集中只有8条OH的记录,所以导致如下错误:

错误:样本量 11 大于抽样单位数 8。

UPDATE (7/14/21) 我能够通过使用 SELECTALL 选项来解决错误,我也能够从其他州抓取以填补缺失OH 的记录使用 STRATA 的 ALLOC 选项,所以我更新的 SURVEYSELECT 语句现在看起来像这样。

    ```PROC SURVEYSELECT DATA=UniqueList OUT=UniqueListsamp METHOD=SRS SAMPSIZE=&samplesize

SELECTALL NOPRINT; STRATA PROVIDER_STATE / ALLOC=(.2 .2 .2 .2 .2) ; 运行;```

在这种情况下,我想要实现的 是以能够处理输入文件中发现的任意数量状态的方式使 ALLOC 选项发挥作用。我的理解是该选项需要加起来为 1 的硬编码小数,具体取决于所使用的层数(在本例中为 5,因此 1/5 将是 .2 的 5 个实例,加起来总共为 1)。如果我们提前知道状态的总数,这会很好用,但是当代码被实现使用时情况就不会这样了。有没有一种方法可以进行计算(1 / 状态数 = .2),然后输入该值的次数与找到的状态数一样多,用逗号或 space (.2 .2 .2 . 2 .2) 进入ALLOC选项?

您可以将数据集作为参数传递给 surveyselect 中的 SAMPSIZE。我想这就是你需要的。

以您的计数为起点,我首先创建一个与您的实际输入相匹配的数据集。然后我 运行 一个表格来让你的计数回来。然后我分析表格以确定要拉多少,每个州有多少,并确保它不会要求太多。这让我们初步了解每个状态将要提取的内容,并为我们提供了一个数据集,让我们可以修改该数字。

如何提取最后 3 个的问题很复杂,因为它并不简单 - 你想如何提取这 3 个?您是否应该“随机”选择状态以添加一个?如果一个州只剩下 1 个,而您实际上每个州想要 3 个怎么办?这样做会有点麻烦,如果您不经常这样做,那么分析性地进行可能会更容易。一个适当的系统将有详细的检查,多次通过,并假设所有可能出错的地方都会出错。

在这个例子中,我只是继续采取“额外” - 所以我抽样 56。这让你非常接近你想要的样本,同时均匀地坚持你的抽样计划比率并且每个州没有不同的数量(在那些可以的州)。如果你想准确地抽取 55 个样本,你需要决定如何将第 12 个分配给 3 个最大的州?到三个随机状态?取决于你,但工作是相似的。

data for_gen;
  input state $ count;
  do id = 1 to count;
    state_id = cats(state,put(id,z3.));
    output;
  end;
  keep state state_id;
  datalines;
IN 100
KY 217
MO 189
OH 8
WI 36
;;;;
run;

*create a listing, including the overall row (which will be on top);
proc tabulate data=for_gen out=state_counts(keep=state n); 
  class state;
  table (all state),n;
run;

*now distribute the sample, first pass;
data sample_counts;
  set state_counts nobs=statecount end=eof;
  retain total_sample sample_per_state states_left;
  if _n_ = 1 then do;
    *the sample size rules;
    if n lt 500 then total_sample = min(50,n);
    else total_sample = min(100,floor(n/10));   
    *how many per state;
    sample_per_state = ceil(total_sample/(statecount-1)); *or maybe floor?;
  end;
  else do;
    *here we are in the per-state section;
    _NSIZE_ = min(n,sample_per_state);
    *allocate sample amounts, remove the used sample quantity from the total quantity, and keep track of how many states still have sample remaining;
    total_sample = total_sample - _NSIZE_;
    if n ne _nsize_ then states_left+1;
  end;
  *save the remaining info in macro variables to use later;
  if eof then do;
    call symputx('sample_left',total_sample);
    call symputx('states_left',states_left);
  end;
  if state ne ' ' then output;
run;


*allocate the remaining sample - we assume we want "at least" the sample count; 
data sample_secondpass;
  set sample_counts end=eof;
  retain total_sample_left &sample_left.
         total_states_left  &states_left.
         leftover     0 
         ;
  if total_sample_left gt 0 and total_states_left gt 0 then do;
     per_state = ceil(total_sample_left/total_states_left);
    if n gt (_nsize_ + per_State) then do; 
        _nsize_ = _nsize_ + per_state;
    end;
    else do;
        leftover = leftover + (_nsize_ + per_state - n);
        _nsize_ = n;
    end;
  end;
  if eof then call symputx('leftover',leftover);
run;


* Use the sample counts dataset to run the surveyselect;
proc surveyselect sampsize=sample_secondpass data=for_gen;
strata state;
run;