SAS如何按组随机选择随机分成多个组

SAS how to get random selection by group randomly split into multiple groups

我有一个简单的客户数据集(大约 40,000k) 看起来像:

customerid, group, other_variable
a,blue,y
b,blue,x
c,blue,z
d,green,y
e,green,d
f,green,r
g,green,e

我想为每个组随机 select Y 数量的客户(以及他们的其他变量)。 问题是,我想为每组随机分配两个 Y 量的 select 离子 即

4000 random green customers split into two sets of 2000 randomly
and 4000 random blue customers split into two sets of 2000 randomly

这是因为我有不同的信息要给两个不同的分组 我不是用替换抽样。需要是独特的客户

更喜欢 PROC SQL 中的解决方案,但如果 proc sql 不理想,则更喜欢 sas 中的替代解决方案

data custgroup ;
do i=1 to nobs;
set sorted_data nobs=nobs ;
point = ranuni(0);
end;

proc sort data = custgroup out=sortedcust
by group point;
run;

data final;
set sortedcust;
by group point;
if first group then i=1;
i+1;
run;

基本上我所做的是首先为数据集中的所有观察值分配一个随机数。然后根据变量grouppoint进行排序。

现在我实现了组内观察的随机顺序。 i=1i+1 将是确定组内的观察行。这意味着将避免提取重复的观察结果。还可以使用 output 语句来控制要根据 i.

存储观察结果的位置

我的方法可能不是最有效的方法。

proc surveyselect 是 SAS 中随机抽样的通用选择工具。代码非常简单,我只对每个组采样 4000 个,然后每 2000 行分配一个新的子组,因为数据无论如何都是随机顺序的(尽管按组排序)。

proc surveyselect默认的抽样方式是srs,就是简单的无放回随机抽样,正是这里所需要的。

这是一些示例代码。

/* create dummy dataset */
data have;
do customerid = 1 to 10000;
length group other_variable ;
if rand('uniform')<0.5 then group = 'blue'; /* assign blue or green with equal likelihood */
    else group = 'green';
other_variable = byte(97+(floor((1+122-97)*rand('uniform')))); /* random letter between a and z */
output;
end;
run;

/* dataset must be sorted by group variable */
proc sort data=have;
by group;
run;

/* extract random sample of 4000 from each group */
proc surveyselect data=have
                    out=want
                    n=4000
                    seed=12345; /* specify seed to enable results to be reproduced */
strata group; /* set grouping variable */
run;

/* assign a new subgroup for every 2000 rows */
data want;
set want;
sub=int((_n_-1)/2000)+1;
run;

下面的代码应该可以做到。首先,您需要生成一个随机数。正如 Joe 上面所说,最好用特定的数字作为种子,以便您可以在必要时重现样本。然后你可以使用 Proc Sql 和 outobs 语句来生成样本。

(顺便说一句,最好不要将变量命名为 'group'。)

data YourDataSet;
set YourDataSet;
myrandomnumber = ranuni(123);
run;

proc sql outobs=2000;
create table bluesample as
select *
from YourDataSet
where group eq 'blue'
order by myrandomnumber;
quit;

proc sql outobs=2000;
create table greensample as
select *
from YourDataSet
where group eq 'green'
order by myrandomnumber;
quit;