SASによるシミュレーション#

ここではSASで利用できるいくつかの乱数生成関数について説明します。

  • 大規模なデータセットからランダムな標本を抽出する

  • ランダム化比較実験における被験者への処置割り当て計画を作成する

  • 基本的な確率分布に従う乱数を生成する (シミュレートする)

ここで使用される乱数生成関数には以下のようなものがあります。

  • ranuni: 0 から 1 までの一様分布に従って乱数を生成します。

  • rannor: 標準正規分布に従って乱数を生成します。

  • ranbin: n 回の試行で成功確率が p のベルヌーイ試行から乱数を生成します。

  • ranpoi: 平均 m のポアソン分布に従って乱数を生成します。

ここでは取り上げませんが、SASには他にも様々な乱数生成関数があります。例えば、コーシー分布 (rancau)、ガンマ分布 (rangam)、三角分布 (rantri)、指数分布 (ranexp)、個別確率を指定した離散分布 (rantbl) などがあります。

以降に進むにあたっては、主にデータステップで利用できるツールを活用します。具体的には、DOループ、IF-THEN-ELSE ステートメント、RETAIN ステートメント、OUTPUT ステートメントなどです。このようなアプローチを取ることで、データステップの便利なテクニックを確認して実践するだけでなく、ランダムサンプリング、ランダム割り当て、シミュレーションのプロセスをより深く理解することができます。

ただし、ランダムサンプリングに関しては、データステップに加えて、将来的に役立つよう基本的な機能を知ってもらうために、SURVEYSELECT プロシジャも使用します。コースの時間の制約と PLAN プロシジャの複雑さから、ランダム割り当ての実行には PLAN プロシジャを使用しません。しかし、興味があれば自分で確認してみることをお勧めします。

非復元無作為抽出#

大規模なデータセットからレコードをランダムに選択することは、データセットが大きすぎて処理ができない・時間がかかる場合、あるいは調査を実施していてマスターデータベースからランダムな標本を選択する必要がある場合に役立ちます。

大きなデータセット (またはマスターデータベース) からレコードをランダムに選択する場合、いくつかの方法があります。

  • 非復元抽出: オブザベーションの一部がランダムに選択され、一度選択されたオブザベーションは再度選択されません。

  • 復元抽出: オブザベーションの一部がランダムに選択され、一つのオブザベーションが複数回選択される可能性があります。

  • 層化抽出: 層化変数の値で定義された各グループからオブザベーションの一部がランダムに選択され、一度選択されたオブザベーションは再度選択されません。

ここでは、無標本抽出について説明し、その後復元抽出と層化抽出について説明します。

これらでは、架空の宛先リストを使用します。このリストは、大規模なカタログ通販会社が顧客の一部を対象としたランダムな調査を実施したいと考えているシナリオで用います。使用する実際のリストは、実務で使用するものよりもはるかに小さいものですが、ランダムサンプリング手法を説明する目的でのみ使用されます。

使用する宛先リストは、永久データセットmailingに格納されています。次のコードは、単に宛先リストを出力するものです。

libname phc6089 '/folders/myfolders/SAS_Notes/data';

title 'Sample Dataset: Mailing List'; 
proc print data=phc6089.mailing(obs=5);    
run;
SAS 出力

Sample Dataset: Mailing List

OBS Num Name Street City State
1 1 Jonathon Smothers 103 Oak Lane Bellefonte PA
2 2 Jane Doe 845 Main Street Bellefonte PA
3 3 Jim Jefferson 10101 Allegheny Street Bellefonte PA
4 4 Mark Adams 312 Oak Lane Bellefonte PA
5 5 Lisa Brothers 89 Elm Street Bellefonte PA

データセットmailing.sas7bdatは、READMEに記載しているデータフォルダにあります。データセットを保存した場所を反映するように LIBNAME ステートメントを編集してください。プログラムを実行して生成された出力からデータセットの内容を確認してください。

SAS などのコンピュータプログラムを使用して、大きなデータセットから一部のオブザベーションをランダムに選択する場合には、2 つの方法があります。データセット内のオブザベーションの一定割合 (例えば 30%) をランダムに選択するような指示と、データセット内から特定の個数 (例えば 25 個) のオブザベーションをランダムに選択するように指示があります。前者の方法では、抽出されたデータセットが特定のサイズになることは保証されません。このような標本は「近似サイズの標本」とみなします。一般に、近似サイズの標本を取得するには、元のデータセットから k% のオブザベーションを選択します。

#

次のプログラムは、データステップを使用して無標本抽出による近似サイズのランダム標本を取得する方法を示しています。具体的には、ranuni 関数と WHERE ステートメントを使用して、50オブザベーションの永久データセット mailing から約 30%をランダムにサンプリングします。

data sample1A (where = (random <= 0.30));
  set phc6089.mailing;
  random = ranuni(43420);
run;

title1 'Sample1A: Approximate-Sized Simple Random Sample';
title2 'without Replacement'; 
proc print data=sample1A noobs;
run;
SAS 出力

Sample1A: Approximate-Sized Simple Random Sample

without Replacement

Num Name Street City State random
1 Jonathon Smothers 103 Oak Lane Bellefonte PA 0.07478
2 Jane Doe 845 Main Street Bellefonte PA 0.25203
4 Mark Adams 312 Oak Lane Bellefonte PA 0.08918
6 Delilah Fequa 2094 Acorn Street Bellefonte PA 0.02253
7 John Doe 812 Main Street Bellefonte PA 0.15570
8 Mamie Davison 102 Cherry Avenue Bellefonte PA 0.05460
9 Ernest Smith 492 Main Street Bellefonte PA 0.05662
14 William Edwards 79 Oak Lane Bellefonte PA 0.15432
38 Miriam Denders 2348 Robin Avenue Port Matilda PA 0.16192
41 Lou Barr 219 Eagle Street Port Matilda PA 0.13033
43 Leslie Olin 487 Bluebird Haven Port Matilda PA 0.23101
44 Edwin Hoch 389 Dolphin Drive Port Matilda PA 0.20708
49 Tim Winters 95 Dove Street Port Matilda PA 0.03722
20 Kristin Jones 120 Stratford Drive State College PA 0.29425
22 Roberta Kudla 312 Whitehall Road State College PA 0.05187
24 Mark Mendel 256 Fraser Street State College PA 0.06246
26 Jan Davison 201 E. Beaver Avenue State College PA 0.00799
31 Robert Williams 156 Straford Drive State College PA 0.14537
34 Mike Dahlberg 1201 No. Atherton State College PA 0.27246
35 Doris Alcorn 453 Fraser Street State College PA 0.24231

プログラムを開いて実行し、生成された出力からランダム標本の内容を確認してください。いくつかの点に注意する必要があります。まず、ランダム標本に含まれる人々は、50までの「Num」の値にわたって比較的均等に分布しているようです。また、最終的なランダム標本には、データセットmailing の50オブザベーションのうち 20オブザベーションが含まれています。これは 40% (20/50) であり、要求していた 30% の標本よりも少し大きくなっていますが、使用した方法の制約によるものです。最後に、変数 「random」 には 0.30 より小さい値しか含まれないことに注意してください。これは、DATA ステートメントのデータセットオプションのWHERE= オプションの影響です。

それでは、このプログラムがどのように動作するかについて説明します。説明に入る前に、この手法は統計学者が一般的に使用する手法であることを念頭に置いてください。この方法は、SAS だけでなく、あらゆるプログラムで動作します。

まず、変数「random」に (擬似) 乱数を生成するために ranuni関数を使用します。ranuni関数は 0 と 1 の間の値を生成します。ranuni関数の引数43420はシードと呼ばれ、ユーザーによって指定されます。一般的に:

  • シードは、2,147,483,647 より小さい非負の数値である必要があります。

  • 特定のシードを使用すると、常に同じ結果が得られます。つまり、同じシードを使用すると、ranuni 関数は常に同じオブザベーションを選択します。

  • シードを 0 に設定すると、実行時のコンピュータクロック時間が使用されます。この場合、ranuni 関数が同じ結果を生成する可能性は非常に低くなります。研究を行う際には、必要に応じて結果を再現できるように、ゼロ以外のシードを使用することが一般的です。

  • ranuni関数は、変数に割り当てずに使用することもできます。ここでは、結果を出力できるように変数「random」に値を割り当てました。

ranuni関数によって生成される数は 0 と 1 の間に一様分布しているので、約 30% の乱数が 0.30 より小さくなることが期待されます。ここで、DATA ステートメントの WHERE= オプションが役割を果たします。乱数が 0.30 以下の場合は、そのオブザベーションが標本に選択されます。データセットmailing には 50ブザベーションがあるため、約 30% のオブザベーションが選択されて、15 人程度の標本が作成されるはずです。ただし、選択は生成された数値に依存するため、標本のサイズは必ずしも一定になるとは限りません。

シードを何度か変更して、標本にどのような影響を与えるかを確認してみるのもよいでしょう。例えば、シードを 1 にすると、新しいランダム標本には 20 個ではなく 15 個のオブザベーションが含まれることがわかります。また、0.30 以外の値に割合を変化させて、標本のサイズにどのような影響を与えるかを確認してみるのもよいでしょう。

#

次のコードは、非復元抽出による近似サイズのランダム標本を取得するための別の方法を示しています。具体的には、SURVEYSELECT プロシジャを使用して、50オブザベーションの永久データセットmailingから約 30%をランダムにサンプリングするように指示します。

title;
proc surveyselect data = phc6089.mailing
  out = sample1B
  method = SRS
  seed = 12345678
  samprate = 0.30;
run;

title1 'Sample1B: Approximate-Sized Simple Random Sample';
title2 'without Replacement (using PROC SURVEYSELECT)'; 
proc print data = sample1B noobs;    
run;
SAS 出力

SURVEYSELECT プロシジャ

選択の方法 Simple Random Sampling
入力データセット MAILING
乱数シード 12345678
標本抽出率 0.3
標本サイズ 15
選択確率 0.3
サンプリングの重み 3.333333
出力データセット SAMPLE1B

Sample1B: Approximate-Sized Simple Random Sample

without Replacement (using PROC SURVEYSELECT)

Num Name Street City State
1 Jonathon Smothers 103 Oak Lane Bellefonte PA
5 Lisa Brothers 89 Elm Street Bellefonte PA
12 Fran Cipolla 912 Cardinal Drive Bellefonte PA
14 William Edwards 79 Oak Lane Bellefonte PA
38 Miriam Denders 2348 Robin Avenue Port Matilda PA
39 Scott Fitzgerald 43 Blue Jay Drive Port Matilda PA
40 Jane Smiley 298 Cardinal Drive Port Matilda PA
44 Edwin Hoch 389 Dolphin Drive Port Matilda PA
45 Ann Draper 72 Lake Road Port Matilda PA
50 George Matre 75 Ashwind Drive Port Matilda PA
19 Frank Smith 238 Waupelani Drive State College PA
24 Mark Mendel 256 Fraser Street State College PA
29 Joe White 678 S. Allen Street State College PA
34 Mike Dahlberg 1201 No. Atherton State College PA
35 Doris Alcorn 453 Fraser Street State College PA

プログラムを開いて実行し、生成された出力をからSURVEYSELECT プロシジャが実際にデータセットmailingから標本を抽出したことを確認してください。ご覧のとおり、SURVEYSELECT プロシジャは 1 ページ分の出力を生成します。これは単に情報提供のみであり、SURVEYSELECT コードで指定した情報の大部分を繰り返すものです。

  • DATA= オプションは、オブザベーションを選択する元のデータセット (phc6089.mailing) の名前を指定します。

  • OUT= オプションは、選択されたオブザベーションを格納する出力データセット (sample1B) の名前を指定します。

  • METHOD= オプションは、使用するサンプリング方法を指定します。ここでは、SRSは等確率で無標本抽出を使用してオブザベーションを選択するようにします。

  • SEED= オプションは、乱数を生成するための初期シード (12345678) を指定します。一般的に、SEED=オプションの値は整数である必要があり、SEED=オプションを指定しない場合、または SEED= 値が負またはゼロの場合、コンピュータクロックが使用されて初期シードが取得されます。

  • SAMPRATE= オプションは、入力データセットから標本化するする割合 (0.30)を指定します。

さて、これまで説明してきたのは、非復元抽出による近似サイズのランダム標本のみです。次に3 つの例から、非復元抽出による厳密なサイズのランダム標本を取得する方法を説明します。最も複雑な方法 (データステップを使用) から最も単純な方法 (SURVEYSELECT プロシジャを使用) まで順を追って説明します。

これまででは非復元抽出による近似のランダム標本を作成しました。次に非復元抽出で厳密なサイズのランダム標本を取得する方法を見ていきます。はじめにデータステップによる比較的複雑な方法で、最後はプロシージャ(SURVEYSELECT)を使う簡単な方法を見ていきます。

#

次のプログラムは、データステップを使用して、非復元抽出による厳密なサイズのランダム標本を取得する方法を示しています。具体的には、ranuni 関数と DATA ステートメントを使用して、永久データセット mailingから 15オブザベーションをランダムにサンプリングするように指示します。

data sample2;
  set phc6089.mailing nobs=total;
  if _n_ = 1 then n=total;
  retain k 15 n;
  random = ranuni(860244);
  propn = k/n;
  if random <= propn then
    do;
      output;
      k=k-1;
  end;
  n=n-1;
  if k=0 then stop;
run;

title1 'Sample2: Exact-Sized Simple Random Sample';
title2 'without Replacement'; 
proc print data=sample2 noobs;
  var num name n k random propn;
run;
SAS 出力

Sample2: Exact-Sized Simple Random Sample

without Replacement

Num Name n k random propn
4 Mark Adams 47 15 0.12829 0.31915
5 Lisa Brothers 46 14 0.08799 0.30435
6 Delilah Fequa 45 13 0.02446 0.28889
9 Ernest Smith 42 12 0.01228 0.28571
14 William Edwards 37 11 0.12908 0.29730
15 Harold Harvey 36 10 0.03136 0.27778
41 Lou Barr 32 9 0.11230 0.28125
46 Linda Nicolson 27 8 0.10826 0.29630
16 Linda Edmonds 22 7 0.26260 0.31818
23 Greg Pope 15 6 0.17021 0.40000
25 Steve Lindhoff 13 5 0.36375 0.38462
28 Srabashi Kundu 10 4 0.08095 0.40000
33 Steve Ignella 5 3 0.56556 0.60000
34 Mike Dahlberg 4 2 0.35489 0.50000
36 Daniel Fremgen 2 1 0.14088 0.50000

プログラムを開いて実行し、結果から実際に宛先のデータセットから15オブザベーションが選択されていることを確認してください。

サンプルを選択するために使用した方法は次のとおりです。

  • データセット内の各オブザベーションに対して、一様乱数を生成します。

  • 元のデータセットの最初のオブザベーションが、その乱数が必要なレコードの割合(50件中15件、つまり0.30)以下であれば、サンプルに含めます。

  • サンプルでまだ必要な割合を変更します。最初のオブザベーションがサンプルに含まれた場合は14/49、含まれなかった場合は15/49になります。2番目のオブザベーションに対して生成された乱数がこの割合以下であれば、サンプルに含めます。

  • 15件のオブザベーションを正確に選択するまで、このプロセスを続けます。

では、データステップを使用してこの方法を実行するにはどうすればよいでしょうか。以下では順を追って説明します。

  • k:サンプルを完成させるために必要なオブザベーションの数

  • n:元のデータセットから読み取る残りのオブザベーションの数

2つの変数kとnを定義します。

  • SETステートメントのNOBS=オプションを使用して、phc6089.mailingデータセットのオブザベーション数を取得し、変数「total」に割り当てます。一般的に、NOBS=オプションは、SETステートメントで指定されたデータセットのオブザベーションの総数を値とする一時変数を生成し、名前を付けます。

  • 最初のオブザベーションの場合、つまり自動変数「_N_」が1の場合、変数「n」に変数「total」の値(ここでは50)を設定します。(自動変数はデータステップによって自動的に作成され、プログラムデータベクトルに追加されますが、作成されているデータセットに出力されません。自動変数の値は、データステップの1回の反復から次の反復まで保持され、欠損値に設定されることはありません。自動変数_N_は最初に1に設定されます。データステップがDATAステートメントをループするたびに、変数「_N_」は1ずつ増加します。「_N_」の値はデータステップが反復した回数で、多くの場合出力データセットのオブザベーション数を表します。)

  • RETAINステートメントを使用して、kを最終サンプルで必要なオブザベーション数である15に初期化します。

  • ranuni関数(シード860244から開始)を使用して、0から1の一様乱数を生成します。kとnを使用して、データセットmailingからまだ選択する必要があるオブザベーションの割合を決定します。

  • 生成された乱数が、まだ必要なオブザベーションの割合より小さい場合、そのオブザベーションを出力データセットに出力します。オブザベーションが選択された場合、サンプルでまだ必要なオブザベーション数を1減らします(つまり、k = k-1)。

  • データステップの各反復の最後に、

    • データセットmailingに残っているオブザベーション数を1減らします(n = n - 1)。

    • サンプリングが完了しているかどうかを判断します(k = 0?)。完了している場合は、中止するように指示します。一般的に、STOPステートメントは、現在のデータステップの処理をすぐに停止し、以降の処理から再開します。

random = ranuni()とpropn = k/nの割り当ては、これらの値を出力できるようにするためにのみ行われます。これらの値はif ranuni() le k/n then do;のようにIFステートメントに直接組み込まれることもあります。またkとnは出力データセットから削除できますが、ここでは、教育目的のために値を出力できるように保持されています。

#

以下のコードはデータステップにより非復元抽出による厳密なサイズのランダム標本を取得する他の方法を示しています。このコードでは2つのデータステップとソートは必要なため効率的ではないですが、こちらの処理のほうが自然でわかりやすいかもしれません。

data sample3A;
  set phc6089.mailing;
  random=ranuni(860244);
run;
 
proc sort data=sample3A;
  by random;
run;
 
data sample3A;
  set sample3A;
  if _n_ <= 15;
run;

title1 'Sample3A: Exact-Sized Simple Random Sample';
title2 'without Replacement'; 
proc print data=sample3A;
run;
SAS 出力

Sample3A: Exact-Sized Simple Random Sample

without Replacement

OBS Num Name Street City State random
1 9 Ernest Smith 492 Main Street Bellefonte PA 0.01228
2 6 Delilah Fequa 2094 Acorn Street Bellefonte PA 0.02446
3 15 Harold Harvey 480 Main Street Bellefonte PA 0.03136
4 28 Srabashi Kundu 112 E. Beaver Avenue State College PA 0.08095
5 5 Lisa Brothers 89 Elm Street Bellefonte PA 0.08799
6 46 Linda Nicolson 71 Liberty Terrace Port Matilda PA 0.10826
7 41 Lou Barr 219 Eagle Street Port Matilda PA 0.11230
8 4 Mark Adams 312 Oak Lane Bellefonte PA 0.12829
9 14 William Edwards 79 Oak Lane Bellefonte PA 0.12908
10 36 Daniel Fremgen 103 W. College Avenue State College PA 0.14088
11 23 Greg Pope 5100 No. Atherton State College PA 0.17021
12 16 Linda Edmonds 410 College Avenue State College PA 0.26260
13 38 Miriam Denders 2348 Robin Avenue Port Matilda PA 0.32450
14 13 James Whitney 104 Pine Hill Drive Bellefonte PA 0.33555
15 34 Mike Dahlberg 1201 No. Atherton State College PA 0.35489

プログラムを開いて実行し、結果として得られた出力から実際に宛先データセットから15オブザベーションが選択されたことを確認してください。
このアプローチは、以前に行った非復元抽出での近似サイズの選択の方法と非常に似ています。つまり:

  • データセットの各オブザベーションに対して、ranuni関数を使用して一様乱数を生成し、それを変数「random」に格納します。

  • データセットを乱数「random」でソートします。

  • 自動変数_N_を使用して、ソートされたデータセットから最初の15オブザベーションを選択します(if _N_ <= 15)。

こうすることで、宛先データセット内のすべてのオブザベーションが先頭15オブザベーションのうちの1つになる可能性が等しくなり、したがってサンプルに選ばれる可能性も等しくなります。

#

以下のコードは、非復元抽出による厳密なサイズのランダム標本を取得する別の方法を示しています。具体的には、SURVEYSELECTプロシージャを使用して、50オブザベーションの永久データセットmailingから正確に15オブザベーションをランダムにサンプリングします。

title;
proc surveyselect data = phc6089.mailing
  out = sample3B
  method = SRS
  seed = 12345678
  sampsize = 15;    
run;

title1 'Sample3B: Exact-Sized Simple Random Sample';
title2 'without Replacement (using PROC SURVEYSELECT)'; 
proc print data = sample3B;
run;
SAS 出力

SURVEYSELECT プロシジャ

選択の方法 Simple Random Sampling
入力データセット MAILING
乱数シード 12345678
標本サイズ 15
選択確率 0.3
サンプリングの重み 3.333333
出力データセット SAMPLE3B

Sample3B: Exact-Sized Simple Random Sample

without Replacement (using PROC SURVEYSELECT)

OBS Num Name Street City State
1 1 Jonathon Smothers 103 Oak Lane Bellefonte PA
2 5 Lisa Brothers 89 Elm Street Bellefonte PA
3 12 Fran Cipolla 912 Cardinal Drive Bellefonte PA
4 14 William Edwards 79 Oak Lane Bellefonte PA
5 38 Miriam Denders 2348 Robin Avenue Port Matilda PA
6 39 Scott Fitzgerald 43 Blue Jay Drive Port Matilda PA
7 40 Jane Smiley 298 Cardinal Drive Port Matilda PA
8 44 Edwin Hoch 389 Dolphin Drive Port Matilda PA
9 45 Ann Draper 72 Lake Road Port Matilda PA
10 50 George Matre 75 Ashwind Drive Port Matilda PA
11 19 Frank Smith 238 Waupelani Drive State College PA
12 24 Mark Mendel 256 Fraser Street State College PA
13 29 Joe White 678 S. Allen Street State College PA
14 34 Mike Dahlberg 1201 No. Atherton State College PA
15 35 Doris Alcorn 453 Fraser Street State College PA

プログラムを開いて実行し、結果として得られた出力から実際に宛先データセットから15のオブザベーションが選択されたことを確認してください。このコードと前のSURVEYSELECTによるコードの唯一の違いは、ここでのsampsize = 15が、前のコードのsamprate = 0.30に置き換わっていることです。シード(seed)とサンプルサイズ(sampsize)を数回変更して、サンプルにどのように影響するかを確認してみてください。

復元無作為抽出#

前のセクションでは、選択したすべてのサンプルは復元されませんでした。つまり、データセットからオブザベーションが一度選択されると、再び選択されることはありませんでした。今度は、復元抽出の方法を見ていきます。つまり、オブザベーションが一度選択されても、それが再び選択されるのを防ぐことはありません。

#

以下のコードは、データステップを使用して正確なサイズのランダムサンプルを復元抽出で選択する方法を示しています。具体的には、ranuni関数とSETステートメントのPOINT=オプションを組み合わせて、永久50オブザベーションのデータセットmailingから正確に15オブザベーションをランダムにサンプリングします。

data sample4A;
  choose=int(ranuni(58)*n)+1;
  set phc6089.mailing point=choose nobs=n;
  i+1;
  if i > 15 then stop;
run;

title1 'Sample4A: Exact-Sized Unrestricted Random Sample';
title2 'Selects units with equal probabilities & with replacement';
proc print data=sample4A;
run;
SAS 出力

Sample4A: Exact-Sized Unrestricted Random Sample

Selects units with equal probabilities & with replacement

OBS Num Name Street City State i
1 24 Mark Mendel 256 Fraser Street State College PA 1
2 14 William Edwards 79 Oak Lane Bellefonte PA 2
3 10 Laura Mills 704 Hill Street Bellefonte PA 3
4 3 Jim Jefferson 10101 Allegheny Street Bellefonte PA 4
5 45 Ann Draper 72 Lake Road Port Matilda PA 5
6 11 Linda Bentlager 1010 Tricia Lane Bellefonte PA 6
7 47 Barb Wyse 21 Cleveland Drive Port Matilda PA 7
8 29 Joe White 678 S. Allen Street State College PA 8
9 32 George Ball 888 Park Avenue State College PA 9
10 31 Robert Williams 156 Straford Drive State College PA 10
11 49 Tim Winters 95 Dove Street Port Matilda PA 11
12 42 Casey Spears 123 Main Street Port Matilda PA 12
13 47 Barb Wyse 21 Cleveland Drive Port Matilda PA 13
14 32 George Ball 888 Park Avenue State College PA 14
15 48 Coach Pierce 74 Main Street Port Matilda PA 15

プログラムを開いて実行し、結果として得られた出力から実際に宛先データセットから15オブザベーションが選択されたことを確認してください。
このコードの理解の鍵は、

choose = int(ranuni(58)*n) + 1

という式が何を行うかを理解することです。
ご存じの通り、ranuni(58)は、初期シード58を使用して0から1の間の一様乱数を生成します。例として0.99を生成したと仮定します。すると、「choose」の値は次のように計算されて50になります:

choose = int(0.99*50) + 1 = int(49.5) + 1 = 49 + 1 = 50

そして、0.01を生成した場合、「choose」の値は次のように計算されて1になります:

choose = int(0.01*50) + 1 = int(0.5) + 1 = 0 + 1 = 1

このようにして、この式は常にデータセットのオブザベーションnまでの正の整数1、2、3、…を生成します。次にこのような乱数を何度も生成させて、希望するサンプルサイズに達するまで繰り返し生成させるだけです。
アプローチの概要は次のとおりです:

  • SETステートメントのNOBS=オプションを使用して、元のデータセットのオブザベーション数nを取得します。

  • 上記のchoose=代入文を使用して、1からnの間の乱数を生成します。(choose=代入ステートメントはSETステートメントの前に配置する必要があります。そうしないと、SASは最初にどのオブザベーションを読み取るかをわからないためです。)

  • SETステートメントのPOINT=オプションを使用して、元のデータセットから「choose」番目のオブザベーションを選択します。POINT=オプションは、オブザベーション番号による直接アクセスを使用してデータセットを読み取ります。一般的に、POINT=オプションを使用すると、一時変数(ここではchoose)の値が読み取るオブザベーションの番号になります。

  • 上記の2つのステップを繰り返し、選択したオブザベーションの数をカウントします。式i + 1はカウントを処理します:デフォルトでは、データステップの最初の反復時にiを0に設定し、その後の各反復でiを1ずつ増やします。

  • 希望するオブザベーション数(ここでは15)を選択したら、STOPするようにします。POINT=オプションを使用する場合、STOPステートメントを使用してデータステップの処理を停止するように指示する必要があることに注意してください。

これで完了です!シード(58)やサンプルサイズ(15)を数回変更して、サンプルにどのように影響するかを確認してみてください。

#

以下のコードは、正確なサイズのランダムサンプルを復元抽出で選択する別の方法を示しています。具体的には、SURVEYSELECTプロシージャを使用して、50オブザベーションの永久データセットmailingから正確に15オブザベーションをランダムにサンプリングします。

title;
proc surveyselect data = phc6089.mailing
  out = sample4B
  method = URS
  seed = 12345
  sampsize = 15;
run;

title1 'Sample4B: Exact-Sized Unrestricted Random Sample';
title2 'Selects units with equal probabilities & with replacement';
title3 '(using PROC SURVEYSELECT)'; 
proc print data = sample4B;
run;
SAS 出力

SURVEYSELECT プロシジャ

選択の方法 Unrestricted Random Sampling
入力データセット MAILING
乱数シード 12345
標本サイズ 15
期待ヒット数 0.3
サンプリングの重み 3.333333
出力データセット SAMPLE4B

Sample4B: Exact-Sized Unrestricted Random Sample

Selects units with equal probabilities & with replacement

(using PROC SURVEYSELECT)

OBS Num Name Street City State NumberHits
1 10 Laura Mills 704 Hill Street Bellefonte PA 1
2 14 William Edwards 79 Oak Lane Bellefonte PA 1
3 15 Harold Harvey 480 Main Street Bellefonte PA 1
4 42 Casey Spears 123 Main Street Port Matilda PA 1
5 45 Ann Draper 72 Lake Road Port Matilda PA 1
6 48 Coach Pierce 74 Main Street Port Matilda PA 1
7 17 Rigna Patel 101 Beaver Avenue State College PA 2
8 20 Kristin Jones 120 Stratford Drive State College PA 1
9 29 Joe White 678 S. Allen Street State College PA 1
10 30 Daniel Peterson 328 Waupelani Drive State College PA 2
11 31 Robert Williams 156 Straford Drive State College PA 1
12 34 Mike Dahlberg 1201 No. Atherton State College PA 1
13 37 Scott Henderson 245 W. Beaver Avenue State College PA 1

プログラムを開いて実行し、結果として得られた出力から実際に宛先データセットから15オブザベーションが選択されたことを確認してください。このコードと前のSURVEYSELECTコードの唯一の違いは、ここでのmethod = URSが、前のコードのmethod = SRSに置き換わっていることです。ここでのURSは、置換ありで等しい確率でオブザベーションを選択する制限なしのランダムサンプリング法を使用します。(前のコードとは指定されたシードも異なりますが、それは関係ありません。)
シード(seed)とサンプルサイズ(sampsize)を数回変更して、サンプルにどのように影響するかを確認してみてください。

層化無作為抽出#

前の2つのセクションでは、オブザベーションが特定のサブグループに属するかどうかに関係なく、データセットからランダムにサンプルを取るようにしていました。調査を実施する際には、特定のサブグループから一定数のオブザベーションがサンプルに含まれるようにすることが重要なことがあります。ここでは、そのような制限について扱います。つまり、このセクションでは、層化変数の値によって決定される各サブグループからランダムに選択されたオブザベーションのサブセットを含む層別ランダムサンプルを取得する方法に焦点を当てます。また、一度選択されたオブザベーションが再び選択されない非復元でのサンプリングに戻ります。

均等割り付けによる層化抽出#

最初に、層化変数の値によって決定される各サブグループから同数のオブザベーションが選択される状況に焦点を当てます。

#

以下のコードは、層化グループから等サイズの層別ランダムサンプルを選択する方法を示しています。具体的には、このコードは、変数「city」の値によって決定される3つのサブグループ — State College、Port Matilda、Bellefonte — からそれぞれ5つのオブザベーションをランダムに選択します。

proc freq data=phc6089.mailing;
  table city / out=bycount noprint;
run;
 
proc sort data=phc6089.mailing;
  by city;
run;
 
data sample5;
  merge phc6089.mailing bycount (drop = percent);
  by city;
  retain k;
  if first.city then k=5;
  random = ranuni(109);
  propn = k/count;
  if random le propn then
  do;
    output;
    k=k-1;
  end;
  count=count-1;
run;

title 'Count by CITY'; 
proc print data=bycount;    
run;

title 'Sample5: Stratified Random Sample with Equal-Sized Strata'; 
proc print data=sample5;    
  by city;
run;
SAS 出力

Count by CITY

OBS City COUNT PERCENT
1 Bellefonte 15 30
2 Port Matilda 13 26
3 State College 22 44

Sample5: Stratified Random Sample with Equal-Sized Strata

OBS Num Name Street State COUNT k random propn
1 1 Jonathon Smothers 103 Oak Lane PA 15 5 0.16092 0.33333
2 4 Mark Adams 312 Oak Lane PA 12 4 0.27445 0.33333
3 7 John Doe 812 Main Street PA 9 3 0.18473 0.33333
4 10 Laura Mills 704 Hill Street PA 6 2 0.25575 0.33333
5 12 Fran Cipolla 912 Cardinal Drive PA 4 1 0.10189 0.25000
OBS Num Name Street State COUNT k random propn
6 40 Jane Smiley 298 Cardinal Drive PA 11 5 0.20233 0.45455
7 43 Leslie Olin 487 Bluebird Haven PA 8 4 0.01778 0.50000
8 46 Linda Nicolson 71 Liberty Terrace PA 5 3 0.30759 0.60000
9 48 Coach Pierce 74 Main Street PA 3 2 0.10358 0.66667
10 49 Tim Winters 95 Dove Street PA 2 1 0.16313 0.50000
OBS Num Name Street State COUNT k random propn
11 17 Rigna Patel 101 Beaver Avenue PA 21 5 0.09446 0.23810
12 26 Jan Davison 201 E. Beaver Avenue PA 12 4 0.06831 0.33333
13 28 Srabashi Kundu 112 E. Beaver Avenue PA 10 3 0.15135 0.30000
14 32 George Ball 888 Park Avenue PA 6 2 0.15132 0.33333
15 37 Scott Henderson 245 W. Beaver Avenue PA 1 1 0.21930 1.00000

まずプログラムを開いて実行してください。その後結果として得られた出力から、実際に宛先データセットからBellefonteから5つ、Port Matildaから5つ、State Collegeから5つのオブザベーションが選択されたことを確認してください。
プログラムの動作はどのようになっているのでしょうか?SASで層別ランダムサンプルを選択するためには、基本的に置換なしで等サイズのランダムサンプルを選択するのと似たコードを使用しますが、今回は各サブグループ内で処理します。より具体的には、プログラムは次のステップで動作します:

  • FREQプロシージャの唯一の目的は、層化変数「city」の各水準に対応するphc6089.mailingデータセット内のオブザベーション数を取得することです(したがって、”table city”)。OUT=オプションは変数「city」とその水準のレコード数(count)と割合(percent)を含むデータセットbycountを作成します。

  • SORTプロシージャは、phc6089.mailingデータセットを「city」でソートし、その結果を一時データセットmailingに保存して、次のデータステップで「city」ごとに処理できるようにします。

  • ソートされたデータセットmailingをデータセットbycountと「city」でマージし、サブグループごとのオブザベーション数を利用できるようにします。オブザベーション数の割合は必要ないため、入力時に削除します。

  • データステップの残りのコードは非常に見慣れたものになるはずです。つまり、元のデータセットphc6089.mailing内のサブグループごとのオブザベーション数が利用可能になると、置換なしで等サイズのランダムサンプルを選択するのと同様に、「city」内で選択します(したがって、”by city”)。SASが新しい「city」を読み込むたびに(したがって、”if first.city”)、サブグループのサンプルに必要なオブザベーション数(k)は各サブグループで必要なオブザベーション数(ここでは5)に設定されます。

注:前と同様に、random = ranuni( )およびpropn = k/nの割り当てステートメントは、その値を出力するためだけにあります。これらの値はif ranuni( ) le k/n then do;のようにIFステートメントに直接組み込まれることもあります。さらに、kとcountは出力データセットから削除できますが、教育目的のためにその値を出力するためここでは保持されています。

#

以下のコードは、均等割り付けによる層化抽出別の方法を示しています。このコードは、データセットを2回処理し、1回ソートする必要があるため、効率は低いですが、より自然で直感的に感じられるかもしれません:

data scollege pmatilda bellefnt;
  set phc6089.mailing;
  if city = 'State College' then output scollege;
  else if city = 'Port Matilda'  then output pmatilda;
  else if city = 'Bellefonte'    then output bellefnt;
run;
 
%macro select (dsn, num);
  data &dsn.;
    set &dsn.;
    random=ranuni(85329);
  run;

  proc sort data=&dsn.;
    by random;
  run;
  
  data &dsn.;
    set &dsn.;
    if _n_ <= &num.;
  run;
%mend select;
 
%select(scollege, 5);  %select(pmatilda, 5);  %select(bellefnt, 5); 
 
data sample6A;
  set bellefnt pmatilda scollege;
run;

title 'Sample6A: Stratified Random Sample with Equal-Sized Strata'; 
proc print data=sample6A;    
  by city;
run;
SAS 出力

Sample6A: Stratified Random Sample with Equal-Sized Strata

OBS Num Name Street State random
1 10 Laura Mills 704 Hill Street PA 0.05728
2 4 Mark Adams 312 Oak Lane PA 0.22701
3 13 James Whitney 104 Pine Hill Drive PA 0.28315
4 12 Fran Cipolla 912 Cardinal Drive PA 0.34773
5 5 Lisa Brothers 89 Elm Street PA 0.42637
OBS Num Name Street State random
6 47 Barb Wyse 21 Cleveland Drive PA 0.05728
7 41 Lou Barr 219 Eagle Street PA 0.22701
8 50 George Matre 75 Ashwind Drive PA 0.28315
9 49 Tim Winters 95 Dove Street PA 0.34773
10 42 Casey Spears 123 Main Street PA 0.42637
OBS Num Name Street State random
11 33 Steve Ignella 367 Whitehall Road PA 0.00548
12 25 Steve Lindhoff 130 E. College Avenue PA 0.05728
13 19 Frank Smith 238 Waupelani Drive PA 0.22701
14 31 Robert Williams 156 Straford Drive PA 0.26377
15 28 Srabashi Kundu 112 E. Beaver Avenue PA 0.28315

まず、プログラムを開いて実行します。その後、結果として得られた出力から実際に宛先データセットよりBellefonteから5つ、Port Matildaから5つ、State Collegeから5つのオブザベーションが選択されたことを確認してください。
プログラムはどのように動作するのでしょうか?以下に、このアプローチの概要を示します:

  • 最初のデータステップは、IF-THEN-ELSEステートメントをOUTPUTステートメントと組み合わせて使用し、元のデータセットmailingを「city」の値に基づいていくつかのデータセットに分割します。(ここでは、「city」の各値のために3つのデータセット、つまりscollege、pmatilda、およびbellefntを作成します。)

  • 次に、マクロselectは、無作為非復元抽出の例を模倣します。つまり、マクロは各オブザベーションに対して乱数を生成し、データセットは乱数でソートされ、最初の「num」の数のオブザベーションが選択されます。

  • 次に、マクロselectを「city」の各値のデータセット、つまりscollege、pmatilda、およびbellefntに対して3回呼び出し、それぞれから5つのオブザベーションを選択します。

  • 最後に、最終データステップは、3つのデータセットbellefnt、scollege、およびpmatildaを5つのオブザベーションずつで1つのデータセットsample6Aに連結します。

すべてが終わると、層化グループから等サイズの層別ランダムサンプルを得られます!2つ目のアプローチもチェック完了です。次は最後のアプローチです!

#

以下のコードは、均等割り付けによる層化抽出の別の方法を示しています。具体的には、SURVEYSELECTプロシージャを使用して、永久データセットmailingから「city」の値のサブグループから正確に5オブザベーションをランダムにサンプリングします。

title;
proc surveyselect data = phc6089.mailing
  out = sample6B
  method = SRS
  seed = 12345678
  sampsize = (5 5 5);
  strata city notsorted;
run;

title1 'Sample6B: Stratified Random Sample';
title2 'with Equal-Sized Strata (using PROC SURVEYSELECT)'; 
proc print data = sample6B;
run;
SAS 出力

SURVEYSELECT プロシジャ

選択の方法 Simple Random Sampling
層変数 City
入力データセット MAILING
乱数シード 12345678
層の数 3
総標本サイズ 15
出力データセット SAMPLE6B

Sample6B: Stratified Random Sample

with Equal-Sized Strata (using PROC SURVEYSELECT)

OBS City Num Name Street State SelectionProb SamplingWeight
1 Bellefonte 5 Lisa Brothers 89 Elm Street PA 0.33333 3.0
2 Bellefonte 7 John Doe 812 Main Street PA 0.33333 3.0
3 Bellefonte 8 Mamie Davison 102 Cherry Avenue PA 0.33333 3.0
4 Bellefonte 11 Linda Bentlager 1010 Tricia Lane PA 0.33333 3.0
5 Bellefonte 15 Harold Harvey 480 Main Street PA 0.33333 3.0
6 Port Matilda 41 Lou Barr 219 Eagle Street PA 0.38462 2.6
7 Port Matilda 42 Casey Spears 123 Main Street PA 0.38462 2.6
8 Port Matilda 44 Edwin Hoch 389 Dolphin Drive PA 0.38462 2.6
9 Port Matilda 48 Coach Pierce 74 Main Street PA 0.38462 2.6
10 Port Matilda 50 George Matre 75 Ashwind Drive PA 0.38462 2.6
11 State College 20 Kristin Jones 120 Stratford Drive PA 0.22727 4.4
12 State College 30 Daniel Peterson 328 Waupelani Drive PA 0.22727 4.4
13 State College 32 George Ball 888 Park Avenue PA 0.22727 4.4
14 State College 35 Doris Alcorn 453 Fraser Street PA 0.22727 4.4
15 State College 37 Scott Henderson 245 W. Beaver Avenue PA 0.22727 4.4

まずプログラムを開いて実行します。その後結果として得られた出力から実際に宛先データセットのBellefonteから5つ、Port Matildaから5つ、State Collegeから5つのオブザベーションが選択されたことを確認してください。
コードの詳細について説明します。ここでの新しい要素はSTRATAステートメントとSAMPSIZEステートメントだけです。STRATAステートメントは、変数「city」によって定義された非重複グループに入力データセットstat482.mailingを分割します。NOTSORTEDオプションは、データセットがソートされていないことを伝えるわけではありません。代わりに、NOTSORTEDオプションは、データセット内のオブザベーションが「city」によりグループごとに配置されていて、そのグループが必ずしもアルファベット順に並んでいないことを伝えます。SAMPSIZEステートメントは、「city」の各値のグループから5つのオブザベーションをサンプリングすることを伝えます。

均等割り付けでない層化抽出#

今回は、層化変数の値に基づいてオブザベーションが各サブグループから同じ数でなく選択される状況に焦点を当てます。元のデータセットの各サブグループに均等でないオブザベーション数がある場合、各サブグループから同じ割合のオブザベーションを選択することでこのサンプリング方式を実現できます。ここでも非復元で抽出をするので、一度オブザベーションが選択されると再選択されることはありません。

均等割り付けでない層化抽出を行うために、異なるグループサンプルサイズを前のマクロselectに渡すことができます。別の方法として、各サブグループのオブザベーション数(n)と各サブグループから選択する必要があるオブザベーション数(k)を含むデータセットを作成することもできます。データセットを作成したら、元のデータセットとマージし、前述のように非復元抽出としてオブザベーションをランダムに選択できます。以下の例ではそのアプローチを使用しています。

#

次のコードは、均等割り付けでない層化抽出の方法を示しています。具体的には、このコードは、変数「city」の値に基づいて、Bellefonteから5つ、Port Matildaから6つ、State Collegeから8つのオブザベーションをランダムに選択します。

data nselect;
  set phc6089.mailing (keep = city);
  by city;
  n+1;
  if last.city then do;
    input k;
    output;
    n=0;
  end;
datalines;
5
6
8
;
run;
 
data sample7 (drop = k n);
  merge phc6089.mailing nselect;
  by city;
  if ranuni(7841) <= k/n then
  do;
    output;
    k=k-1;
  end;
  n=n-1;
run;

title 'NSELECT: Count by CITY';
proc print data=nselect;
run;

title 'Sample7: Stratified Random Sample of Unequal-Sized Groups';
proc print data=sample7;    
  by city;
run;
SAS 出力

NSELECT: Count by CITY

OBS City n k
1 Bellefonte 15 5
2 Port Matilda 13 6
3 State College 22 8

Sample7: Stratified Random Sample of Unequal-Sized Groups

OBS Num Name Street State
1 1 Jonathon Smothers 103 Oak Lane PA
2 3 Jim Jefferson 10101 Allegheny Street PA
3 6 Delilah Fequa 2094 Acorn Street PA
4 11 Linda Bentlager 1010 Tricia Lane PA
5 15 Harold Harvey 480 Main Street PA
OBS Num Name Street State
6 38 Miriam Denders 2348 Robin Avenue PA
7 42 Casey Spears 123 Main Street PA
8 43 Leslie Olin 487 Bluebird Haven PA
9 46 Linda Nicolson 71 Liberty Terrace PA
10 48 Coach Pierce 74 Main Street PA
11 49 Tim Winters 95 Dove Street PA
OBS Num Name Street State
12 16 Linda Edmonds 410 College Avenue PA
13 17 Rigna Patel 101 Beaver Avenue PA
14 18 Ade Fequa 803 Allen Street PA
15 21 Amy Kuntz 357 Park Avenue PA
16 24 Mark Mendel 256 Fraser Street PA
17 26 Jan Davison 201 E. Beaver Avenue PA
18 34 Mike Dahlberg 1201 No. Atherton PA
19 35 Doris Alcorn 453 Fraser Street PA

まずプログラムを開いて実行します。その後、結果として得られた出力から実際に宛先データセットからBellefonteから5つ、Port Matildaから6つ、State Collegeから8つのオブザベーションが選択されたことを確認してください。

プログラムの動作はどうなっているのでしょうか?プログラムを理解するための鍵は、最初のデータステップを理解することです。プログラムの残りは、非復元抽出のコードと非常に似ています。最初のデータステップは、「city」、「n」、および「k」の3つの変数を含む一時データセットnselectを作成します。

  • 「city」の各値のオブザベーション数「n」をカウントするために、カウンタ変数「n」と「last.city」変数を使用します。デフォルトでデータステップの最初の繰り返しで「n」を0に設定し、その後、「city」の水準の1つのオブザベーション数をカウントするまでデータステップの各後続の繰り返しで「n」を1ずつ増加させます。

  • 「city」の各値から選択するオブザベーション数を伝えるために、INPUTステートメントとDATALINESステートメントを使用します。「k」の数は「city」の順序でリストされており、ここではBellefonteから5つ、Port Matildaから6つ、State Collegeから8つのオブザベーションをランダムに選択することをS伝えます。

  • 新しいデータセットnselectに「n」と「k」を書き込むために、サブセット化IFステートメントで変数「last.city」を使用します。ここでは、「city」のサブグループ内の最後のレコードを見つけると、「n」と「k」がデータセットnselectに書き込まれ、「n」は次の「city」のオブザベーション数をカウントする準備のために0にリセットされます。

二番目のデータステップは、データセットphc6089.mailingとデータセットnselectをマージして一時データセットsample7を作成します。マージ後、前述の非復元抽出と同様に、「city」の値ごとのオブザベーション数をランダムに選択します。

#

次のコードは、比例割り付けによる層化抽出の別の方法を示しています。このようなサンプルを選択する際に、各グループから選択するオブザベーション数を指定するのではなく、各グループから等しい割合のオブザベーションを選択するようにすることもできます。次のコードはその方法を示しています。具体的には、このコードは、変数「city」の値に基づいて、Bellefonte、Port Matilda、およびState Collegeの3つのサブグループからそれぞれ25%のオブザベーションをランダムに選択するようにします。

data nselect2;
  set phc6089.mailing (keep=city);
  by city;
  n+1;
  if last.city then do;
    k=ceil(0.25*n);
    output;
    n=0;
  end;
run;
 
data sample8 (drop = k n);
  merge phc6089.mailing nselect2;
  by city;
  if ranuni(7841) <= k/n then
    do;
      output;
      k=k-1;
  end;
  n=n-1;
run;

title 'NSELECT2: Count by CITY'; 
proc print data=nselect2; 
run;

title 'Sample8: Stratified Random Sample of Unequal-Sized Groups'; 
proc print data=sample8;    
run;
SAS 出力

NSELECT2: Count by CITY

OBS City n k
1 Bellefonte 15 4
2 Port Matilda 13 4
3 State College 22 6

Sample8: Stratified Random Sample of Unequal-Sized Groups

OBS Num Name Street City State
1 3 Jim Jefferson 10101 Allegheny Street Bellefonte PA
2 6 Delilah Fequa 2094 Acorn Street Bellefonte PA
3 11 Linda Bentlager 1010 Tricia Lane Bellefonte PA
4 15 Harold Harvey 480 Main Street Bellefonte PA
5 38 Miriam Denders 2348 Robin Avenue Port Matilda PA
6 42 Casey Spears 123 Main Street Port Matilda PA
7 46 Linda Nicolson 71 Liberty Terrace Port Matilda PA
8 49 Tim Winters 95 Dove Street Port Matilda PA
9 16 Linda Edmonds 410 College Avenue State College PA
10 17 Rigna Patel 101 Beaver Avenue State College PA
11 18 Ade Fequa 803 Allen Street State College PA
12 24 Mark Mendel 256 Fraser Street State College PA
13 26 Jan Davison 201 E. Beaver Avenue State College PA
14 35 Doris Alcorn 453 Fraser Street State College PA

ここで最も有効なことは、前の例のコードとここでのコードを比較することです。唯一の違いは、サブグループから選択するオブザベーション数「k」を読み取るためにINPUTおよびDATALINESステートメントを使用するのではなく、ここでは切り上げを行う関数ceil()を使用して「k」を決定することです。具体的には、「k」は次のように計算されます:

k=ceil(0.25*n);

例えば、n = 16のサブグループから25%のオブザベーションを選択するように指示した場合、4つのオブザベーションを選択する必要があることがわかります。しかし、n = 15のサブグループから25%のオブザベーションを選択するように指示した場合、計算すると25%の15は3.75になります。3.75のオブザベーションを選択するのは不可能です。ここでceil関数が役立ちます。ceil(argument)は、引数以上の最小の整数を返します。例えば、ceil(3.75)は4を返し、もちろんceil(3.1)、ceil(3.25)、およびceil(3.87)も4を返します。このようにして「k」が決定されると、プログラムの残りは前の例と同じです。

次に、プログラムを開いて実行してみてください。その後、結果の出力から実際に宛先データセットからBellefonte、Port Matilda、およびState Collegeからそれぞれ25%のオブザベーションが選択されたことを確認してください。この場合、オブザベーション数はそれぞれ4、4、および6となります。

#

次のコードは、均等割り付けでない層化抽出のもう1つの方法を示しています。具体的には、このプログラムはSURVEYSELECTプロシージャを使用して、永久データセットphc6089.mailing内の3つのcityサブグループからそれぞれ5つ、6つ、および8つのオブザベーションをランダムにサンプリングします。

title;
proc surveyselect data = phc6089.mailing
  out = sample9
  method = SRS
  seed = 12345678
  sampsize = (5 6 8);
  strata city notsorted;
run;

title1 'Sample9: Stratified Random Sample';
title2 'with Unequal-Sized Strata (using PROC SURVEYSELECT)'; 
proc print data = sample9;
run;
SAS 出力

SURVEYSELECT プロシジャ

選択の方法 Simple Random Sampling
層変数 City
入力データセット MAILING
乱数シード 12345678
層の数 3
総標本サイズ 19
出力データセット SAMPLE9

Sample9: Stratified Random Sample

with Unequal-Sized Strata (using PROC SURVEYSELECT)

OBS City Num Name Street State SelectionProb SamplingWeight
1 Bellefonte 5 Lisa Brothers 89 Elm Street PA 0.33333 3.00000
2 Bellefonte 7 John Doe 812 Main Street PA 0.33333 3.00000
3 Bellefonte 8 Mamie Davison 102 Cherry Avenue PA 0.33333 3.00000
4 Bellefonte 11 Linda Bentlager 1010 Tricia Lane PA 0.33333 3.00000
5 Bellefonte 15 Harold Harvey 480 Main Street PA 0.33333 3.00000
6 Port Matilda 40 Jane Smiley 298 Cardinal Drive PA 0.46154 2.16667
7 Port Matilda 41 Lou Barr 219 Eagle Street PA 0.46154 2.16667
8 Port Matilda 42 Casey Spears 123 Main Street PA 0.46154 2.16667
9 Port Matilda 43 Leslie Olin 487 Bluebird Haven PA 0.46154 2.16667
10 Port Matilda 49 Tim Winters 95 Dove Street PA 0.46154 2.16667
11 Port Matilda 50 George Matre 75 Ashwind Drive PA 0.46154 2.16667
12 State College 20 Kristin Jones 120 Stratford Drive PA 0.36364 2.75000
13 State College 24 Mark Mendel 256 Fraser Street PA 0.36364 2.75000
14 State College 25 Steve Lindhoff 130 E. College Avenue PA 0.36364 2.75000
15 State College 28 Srabashi Kundu 112 E. Beaver Avenue PA 0.36364 2.75000
16 State College 30 Daniel Peterson 328 Waupelani Drive PA 0.36364 2.75000
17 State College 32 George Ball 888 Park Avenue PA 0.36364 2.75000
18 State College 34 Mike Dahlberg 1201 No. Atherton PA 0.36364 2.75000
19 State College 37 Scott Henderson 245 W. Beaver Avenue PA 0.36364 2.75000

理解しやすいですね!このコードと前の例の均等割り付けのコードとの唯一の違いは、ここではサンプルサイズが5、6、および8と指定されていることです。入力データセットに現れる順序で層のサンプルサイズの値をリストする必要があります。簡単ですね。

プログラムを開いて実行してください。その後結果の出力からコードが実際に宛先データセットよりBellefonteから5つ、Port Matildaから6つ、State Collegeから8つのオブザベーションが選択されたことを確認してください。

ランダム割り付けの作成#

ここでは、データセットからオブザベーションの一部をランダムに抽出することから、ランダム化された対照実験においてサンプルに群をランダムに割り当てることに焦点を移します。良いニュースとして、っ復元抽出に使用される技術は、このようなランダム割り付け計画の生成にも容易に拡張できます。

ここでPLANプロシージャの存在を思い出してもらうのが良いでしょう。先に述べたように、時間的制約とPLANプロシージャの複雑さのため、ここでのランダム割り付けでは使用しません。しかし、将来的に自分で探求したい場合には、その存在を知っておくといいでしょう。

#

頭痛による痛みについて、2つの薬(AとB)と1つのプラセボの効果を比較するための実験を行うとします。研究には30人の被験者が参加していますが、10人の被験者を処理Aに、10人の被験者を処理Bに、そして10人の被験者をプラセボにランダムに割り当てる計画を立てる必要があります。以下のプログラムは、その計画を実行します。つまり、1つの因子が3つの水準を持つ完全にランダム化されたデザインで30人の被験者のランダム割り当てを作成します。

data exper1;
  do Unit = 1 to 30;
    output;
  end;
run;
 
data random1;
  set exper1;
  random=ranuni(27407349);
run;
 
proc sort data=random1;
  by random;
run;
 
proc format;
  value trtfmt 1 = 'Placebo'
               2 = 'Drug A'
               3 = 'Drug B';
RUN;
 
DATA random1;
  set random1;
       if _n_ <= 10              then group=1;
  else if _n_ > 10 and _n_ <= 20 then group=2;
  else if _n_ > 20               then group=3;
  format group trtfmt.;
run;

title 'Random Assignment for CRD with One Factor'; 
proc print data = random1 noobs;    
run ;
SAS 出力

Random Assignment for CRD with One Factor

Unit random group
11 0.00602 Placebo
14 0.14366 Placebo
18 0.18030 Placebo
4 0.20396 Placebo
12 0.21271 Placebo
29 0.21515 Placebo
9 0.25440 Placebo
3 0.29567 Placebo
21 0.32816 Placebo
22 0.33889 Placebo
17 0.44446 Drug A
19 0.47514 Drug A
5 0.49087 Drug A
23 0.50231 Drug A
28 0.52765 Drug A
25 0.53381 Drug A
24 0.55448 Drug A
6 0.60245 Drug A
8 0.60772 Drug A
20 0.61191 Drug A
16 0.69616 Drug B
7 0.69824 Drug B
1 0.70305 Drug B
10 0.71145 Drug B
13 0.71217 Drug B
15 0.86676 Drug B
27 0.96330 Drug B
26 0.97864 Drug B
30 0.98660 Drug B
2 0.99081 Drug B

まずプログラムを開いて実行し、実際に目的の計画を生成したことを確認するために結果を見てみましょう。30人の被験者がランダムに処理A、処理B、およびプラセボに10人ずつ割り当てられているのが見えるはずです。

次に、プログラムがどのように機能しているかを確認するためにプログラムを詳しく見てみましょう。最初のデータステップは単純なDOループを使用して、各実験単位(この場合は被験者)のオブザベーションを含む一時データセットexper1を作成します。データセットの唯一の変数である「unit」には、各実験単位に割り当てられた任意のラベル1, 2, …, 30が含まれています。

残りのコードはランダム割り付けを生成します。これを行うために、前で紹介しているコードを拡張します。つまり:

  • 2番目のデータステップでは、ranuni関数を使用して、データセットexper1内の各オブザベーションに対して0から1の間の一様乱数を生成します。結果は一時データセットrandom1に格納されます。

  • データセットrandom1は乱数の順にソートされます。

  • 3番目のデータステップでは、IF-THEN-ELSEを使用して、ソート順の最初の10単位をグループ1に、次の10単位をグループ2に、最後の10単位をグループ3に割り当てます。

  • グループに意味のあるラベルを付けるためにFORMATが定義されます。

  • 最終的なランダム化されたリストが出力されます。

注: ここで作成されたランダム化リストには、誤った人の手に渡ると研究全体の成功を損なう可能性のある情報が含まれています。つまり、盲検が破られます。ユニットと被験者の名前を関連付けるマスターリストを別々に保持し、グループ番号と処理名を関連付ける方が良い(そして一般的な)対応です。国による臨床試験の多くのでは、統計学者もマスターのリストから盲検される”トリプルブラインド”試験が行われます。ここでは説明のために処置をフォーマットしました。

#

2つの因子を持つ完全にランダム化されたデザインのランダム割り当てを作成するには、前の例のIFうてートメントを変更するだけです。以下のプログラムは、因子Aが2レベル、因子Bが3レベル(したがって6つの処置)を持つ30人の被験者の処置のランダム割り当てを生成します。このコードは前の例のコードと似ていますが、IFステートメントが30人の被験者を6つの処置グループに分け、因子AとBのレベルをグループに任意に割り当てる点が異なります。

data random2;
  set exper1;
  random=ranuni(4901);
run;
 
proc sort data=random2;
  by random;
run;
 
data random2;
  set random2;
  if _n_ <= 5 then 
      do;  factorA = 1; factorB = 1;  end;
  else if _n_ >  5 and _n_ <= 10 then 
      do;  factorA = 1; factorB = 2;  end;
  else if _n_ > 10 and _n_ <= 15 then
      do;  factorA = 1; factorB = 3;  end;
  else if _n_ > 15 and _n_ <= 20 then
      do;  factorA = 2; factorB = 1;  end;
  else if _n_ > 20 and _n_ <= 25 then 
      do;  factorA = 2; factorB = 2;  end;
  else if _n_ > 25 and _n_ <= 30 then
      do;  factorA = 2; factorB = 3;  end;
run;

title 'Random Assignment for CRD with Two Factors'; 
proc print data = random2;    
run;
SAS 出力

Random Assignment for CRD with Two Factors

OBS Unit random factorA factorB
1 9 0.04052 1 1
2 21 0.04733 1 1
3 17 0.07038 1 1
4 20 0.11335 1 1
5 19 0.12459 1 1
6 7 0.14093 1 2
7 29 0.23206 1 2
8 10 0.24267 1 2
9 14 0.27161 1 2
10 26 0.28117 1 2
11 4 0.31276 1 3
12 18 0.34512 1 3
13 15 0.37393 1 3
14 28 0.37724 1 3
15 2 0.40480 1 3
16 6 0.42829 2 1
17 23 0.47371 2 1
18 11 0.48031 2 1
19 13 0.48552 2 1
20 12 0.48943 2 1
21 1 0.50155 2 2
22 3 0.53892 2 2
23 16 0.54762 2 2
24 24 0.69272 2 2
25 30 0.74252 2 2
26 5 0.77423 2 3
27 27 0.80270 2 3
28 8 0.82113 2 3
29 25 0.84338 2 3
30 22 0.95571 2 3

まずプログラムを開いて実行し、実際に目的の処置計画を生成したことを確認するために結果を見てみましょう。5人の被験者がA=1, B=1グループに、5人がA=1, B=2グループに、5人がA=1, B=3グループに割り当てられているのがわかるはずです。

次に、前の例のコードと比較すると、唯一の実質的な違いは2つのIFステートメントの違いであることがわかるはずです。前述のように、ここでのIFステトメントは30人の被験者を6つの処理グループに分け、因子AとBのレベルをグループに任意に割り当てます。

#

これまででは、ランダム割り当てはブロック要因を扱うことを含んでいませんでした。ご存知のように、いくつかの実験では不要な変動を減らすためにいくつかの実験単位を一緒にブロックとすることは自然なことです。たとえば、1日に9つ以上の測定を行うことができないとします。この場合、日をブロック要因として扱うのが良いアイデアです。以下のプログラムは、1つの因子が3つのレベルを持つ乱塊法による27人の被験者に対するランダム割り付けを作成します。

data exper2 (drop = j);
  do block = 1 to 3;
    do j = 1 to 9;  
      if block = 1 then do;  
        unit = j;      
        output;  
      end;
      else if block = 2 then do;  
        unit = j + 9;  
        output;  
      end;
      else if block = 3 then do;  
        unit = j + 18; 
        output;  
      end;
    end;
  end;
run;

title 'EXPER2: Definition of Experimental Units'; 
proc print data=exper2;    
run;

data random3;
  set exper2;
  random=ranuni(7214508);
run;

proc sort data=random3;  
  by block random;  
run;

data random3;
  set random3;
  by block;
  
  if first.block then k=0;
  else k=k+1;
  
  if k in (0,1,2) then trt=1;
  else if k in (3,4,5) then trt=2;
  else if k in (6,7,8) then trt=3;
  
  retain k;
run;

title 'Random Assignment for RBD: Sorted in BLOCK-TRT Order';
proc print data=random3 noobs;
run;

proc sort data=random3;   
  by block unit;  
run;

title 'Random Assignment for RBD: Sorted in BLOCK-UNIT Order';
proc print data=random3 noobs;    
run;
SAS 出力

EXPER2: Definition of Experimental Units

OBS block unit
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 1 6
7 1 7
8 1 8
9 1 9
10 2 10
11 2 11
12 2 12
13 2 13
14 2 14
15 2 15
16 2 16
17 2 17
18 2 18
19 3 19
20 3 20
21 3 21
22 3 22
23 3 23
24 3 24
25 3 25
26 3 26
27 3 27

Random Assignment for RBD: Sorted in BLOCK-TRT Order

block unit random k trt
1 5 0.17083 0 1
1 8 0.18781 1 1
1 6 0.19400 2 1
1 9 0.40043 3 2
1 7 0.58852 4 2
1 4 0.60226 5 2
1 3 0.65488 6 3
1 2 0.79977 7 3
1 1 0.93968 8 3
2 12 0.06810 0 1
2 13 0.08280 1 1
2 16 0.23191 2 1
2 15 0.27690 3 2
2 11 0.38198 4 2
2 14 0.66677 5 2
2 18 0.84177 6 3
2 10 0.91906 7 3
2 17 0.93312 8 3
3 21 0.09791 0 1
3 23 0.11455 1 1
3 22 0.21569 2 1
3 20 0.30461 3 2
3 26 0.30534 4 2
3 27 0.32876 5 2
3 24 0.46627 6 3
3 25 0.74756 7 3
3 19 0.91401 8 3

Random Assignment for RBD: Sorted in BLOCK-UNIT Order

block unit random k trt
1 1 0.93968 8 3
1 2 0.79977 7 3
1 3 0.65488 6 3
1 4 0.60226 5 2
1 5 0.17083 0 1
1 6 0.19400 2 1
1 7 0.58852 4 2
1 8 0.18781 1 1
1 9 0.40043 3 2
2 10 0.91906 7 3
2 11 0.38198 4 2
2 12 0.06810 0 1
2 13 0.08280 1 1
2 14 0.66677 5 2
2 15 0.27690 3 2
2 16 0.23191 2 1
2 17 0.93312 8 3
2 18 0.84177 6 3
3 19 0.91401 8 3
3 20 0.30461 3 2
3 21 0.09791 0 1
3 22 0.21569 2 1
3 23 0.11455 1 1
3 24 0.46627 6 3
3 25 0.74756 7 3
3 26 0.30534 4 2
3 27 0.32876 5 2

ご覧のとおり、データセットexper2は各実験単位(ここでは27人の被験者)のオブザベーションを含むように作成されています。変数「unit」には各実験単位に割り当てられた任意のラベル(1, 2, …, 30)が含まれています。変数「block」はブロック番号(1, 2, 3)を識別し、実験単位を9つずつ3つの等しいサイズのブロックに分けます。

次に、ランダム割り付けを作成するために:

  • 各オブザベーションに対して0から1の間の一様乱数を生成するためにranuni関数を使用します。

  • 次に、各ブロック内でデータを乱数の順にソートします。

  • 次に、各ブロック内のオブザベーション数をカウントするためのカウンタ変数を作成します。各ブロックの最初のオブザベーション(”if first.block”)ではカウンタ(k)を0に設定し、それ以外の場合はブロック内の各オブザベーションごとにカウンタを1ずつ増やします(これを機能させるためには、kを反復ごとに保持する必要があります)。

  • IF-THEN-ELSEを使用して、各ブロック内でソート順の最初の3つのunit(k=0,1,2)をグループ1に、次の3つのunit(k=3,4,5)をグループ2に、最後の3つのunit(k=6,7,8)をグループ3に割り当てます。

実験がどのように行われるかに応じて、異なる順序でランダム割り付けをすることができます:

  • 最初に、処理の順序で各ブロック内でランダム化します。これは、ランダム化された実験単位に対してグループで処置を行うのが自然であるような実験に適します。

  • 次に、ブロック内の単位の順序でランダム化を印刷します。これは、連続する実験単位にランダムな順序で処置を行うのが自然であるような実験に適します。

乱数のシミュレーション#

統計研究では、特定の確率分布に従う数値を生成(つまり、「シミュレーション」)することが一般的な方法です。幸いなことに、SASには特定の確率分布を持つランダム現象をシミュレートするためのいくつかの乱数生成関数があります。ここでは、その中の3つの関数について簡単に見てみましょう。他の関数もここで紹介するものと同様に動作します。

#

以下のプログラムは、平均140、標準偏差20の200個のランダムな正規変数を生成するためにrannor()関数を使用します。

data simula1;
  do i = 1 to 200;
    x = 140 + 20*rannor(3452083);
    output;
  end;
run;

title1 'Simulated Normal Variate';
title2 'with Mean 140 and Standard Deviation 20'; 
proc univariate data=simula1 plot;
  var x;
run;
SAS 出力

Simulated Normal Variate

with Mean 140 and Standard Deviation 20

UNIVARIATE プロシジャ

変数 : x

モーメント
N 200 重み変数の合計 200
平均 140.735977 合計 28147.1955
標準偏差 17.7951858 分散 316.668638
歪度 -0.2457294 尖度 -0.0197441
無修正平方和 4024340.13 修正済平方和 63017.0591
変動係数 12.6443758 平均の標準誤差 1.25830966
基本統計量
位置 ばらつき
平均 140.7360 標準偏差 17.79519
中央値 140.6105 分散 316.66864
最頻値 . 範囲 97.68601
    四分位範囲 23.73450
 位置の検定 H0: Mu0=0
検定 統計量 p 値
Student の t 検定 t 111.8453 Pr > |t| <.0001
符号検定 M 100 Pr >= |M| <.0001
符号付順位検定 S 10050 Pr >= |S| <.0001
 分位点 (定義 5)
水準 分位点
100% 最大値 187.6195
99% 177.7766
95% 168.5732
90% 164.1271
75% Q3 153.7170
50% 中央値 140.6105
25% Q1 129.9825
10% 118.6743
5% 109.5800
1% 95.7932
0% 最小値 89.9334
極値
最小値 最大値
Obs Obs
89.9334 175 170.514 110
95.4514 47 176.143 4
96.1350 133 176.355 127
96.7819 35 179.198 199
96.8844 62 187.619 181
x のプロット

**rannor()**関数は、平均0、標準偏差1の標準正規分布から(疑似)乱数を返します。x=割り当てステートメントは、乱数を平均140、標準偏差20の正規分布からのものに変更します。OUTPUTステートメントは、DOループの各反復後に乱数を出力するために使用されなければなりません。OUTPUTステートメントが存在しない場合、最後に生成された1つの乱数だけが得られます。ちなみに、**rannor()関数はnormal()**関数の別名(エイリアス)です。

プログラムを開いて実行し、UNIVARIATEプロシージャの出力をレビューしましょう。データが正規分布から生じたことを確信できるようにするために、幹葉プロット、箱ひげ図、および正規確率プロットが表示されるはずです。また、200オブザベーションのサンプル平均とサンプル標準偏差が、それぞれ140と20にどれだけ近いか(効果的に)確認することもできます。

#

以下のプログラムは、n = 20、p = 0.5の二項分布から20オブザベーションのランダムサンプルを生成するためにranbin(seed, n, p)関数を使用します。

data simula2;
  do i = 1 to 20;
    b = ranbin(2340234,20,0.5);
    output;
  end;
run;

title1 'Simulated Binomial Variate';
title2 'with n = 20 and p = 0.5';    
proc univariate data=simula2 plot;
  var b;    
run;
SAS 出力

Simulated Binomial Variate

with n = 20 and p = 0.5

UNIVARIATE プロシジャ

変数 : b

モーメント
N 20 重み変数の合計 20
平均 10.1 合計 202
標準偏差 1.51830931 分散 2.30526316
歪度 -0.9884422 尖度 1.25977357
無修正平方和 2084 修正済平方和 43.8
変動係数 15.0327654 平均の標準誤差 0.33950428
基本統計量
位置 ばらつき
平均 10.10000 標準偏差 1.51831
中央値 10.50000 分散 2.30526
最頻値 11.00000 範囲 6.00000
    四分位範囲 2.00000
 位置の検定 H0: Mu0=0
検定 統計量 p 値
Student の t 検定 t 29.74926 Pr > |t| <.0001
符号検定 M 10 Pr >= |M| <.0001
符号付順位検定 S 105 Pr >= |S| <.0001
 分位点 (定義 5)
水準 分位点
100% 最大値 12.0
99% 12.0
95% 12.0
90% 12.0
75% Q3 11.0
50% 中央値 10.5
25% Q1 9.0
10% 8.5
5% 7.0
1% 6.0
0% 最小値 6.0
極値
最小値 最大値
Obs Obs
6 8 11 14
8 11 11 20
9 19 12 6
9 17 12 15
9 13 12 18
b のプロット

プログラムを開いて実行し、UNIVARIATEプロシージャの出力を確認しましょう。20オブザベーションのサンプル平均とサンプル標準偏差が、それぞれ10(np)および2.24(np(1-p)の平方根)にどれだけ近いか(効果的に)確認することもできます。

#

以下のプログラムは、平均4のポアソン分布から200オブザベーションのランダムサンプルを生成するためにranpoi(seed, mean)関数を使用します。

data simula3;
  do i = 1 to 200;
    p = ranpoi(67, 4);
    output;
  end;
run;

title 'Simulated Poisson Variate with Mean 4';
proc univariate data=simula3 plot;    
  var p;
run;
SAS 出力

Simulated Poisson Variate with Mean 4

UNIVARIATE プロシジャ

変数 : p

モーメント
N 200 重み変数の合計 200
平均 3.84 合計 768
標準偏差 2.0943571 分散 4.38633166
歪度 0.77122877 尖度 0.7413239
無修正平方和 3822 修正済平方和 872.88
変動係数 54.5405495 平均の標準誤差 0.14809341
基本統計量
位置 ばらつき
平均 3.840000 標準偏差 2.09436
中央値 3.000000 分散 4.38633
最頻値 3.000000 範囲 12.00000
    四分位範囲 3.00000
 位置の検定 H0: Mu0=0
検定 統計量 p 値
Student の t 検定 t 25.92958 Pr > |t| <.0001
符号検定 M 97.5 Pr >= |M| <.0001
符号付順位検定 S 9555 Pr >= |S| <.0001
 分位点 (定義 5)
水準 分位点
100% 最大値 12.0
99% 9.5
95% 8.0
90% 7.0
75% Q3 5.0
50% 中央値 3.0
25% Q1 2.0
10% 1.5
5% 1.0
1% 0.0
0% 最小値 0.0
極値
最小値 最大値
Obs Obs
0 199 9 133
0 177 9 148
0 132 9 197
0 71 10 2
0 62 12 61
p のプロット

プログラムを開いて実行し、UNIVARIATEプロシージャの出力を確認しましょう。200オブザベーションのサンプル平均とサンプル標準偏差が、それぞれ4および2にどれだけ近いか(効果的に)確認することもできます。

演習#

  1. この例では、母比率の標本分布を扱います。
    a) n = 1、p = 0.3の二項分布からサイズ50の500個のサンプルを生成してください。これを行うために、この二項分布からのランダム変量で埋められた500行50列のデータセットを生成します。ヒント:配列とネストされたDOループを使用します。
    b) mean(of )を使用して、これら500行の各行の平均を計算し、この平均を新しい列として保存してください。
    c) part bで計算された500個の平均のヒストグラムをプロットし、part bで計算された500個の平均からの平均と標準偏差を計算するためにPROC MEANSを使用してください。これは、サンプルサイズが30のときに成功確率p = 0.3の母集団分布を持つ場合のp-hatの標本分布を表しています。