2010年1月22日星期五

實驗組與對照組一對一或一對多簡單配對

以下只是簡單介紹如何使用SAS語法做出實驗組與對照組在配對樣本時的簡單方法


一對一配對資料

先準備實驗組與對照組資料

data case;
input id name$ sex age BMI;
cards;
1 a 1 20 20
2 b 1 21 20
3 c 1 22 21
4 d 1 23 21
5 e 1 24 22
6 f 2 25 22
7 g 2 26 23
8 h 2 27 23
9 i 2 28 24
10 j 2 29 24
;
run;
data control;
input id name$ sex age BMI;
cards;
1 c1 2 29 24
2 c2 2 28 24
3 c3 2 27 20
4 c4 2 26 20
5 c5 2 25 21
6 c6 1 20 22
7 c7 1 21 21
8 c8 1 22 22
9 c9 1 23 23
10 c10 1 24 23
;
run;


若想要做到配對,其配對條件為性別配對
每一筆皆有可能被對應到的結果如下


若為年齡或其他條件配對,其結果也是相似的。

case組每一筆觀察值皆對應到control組符合條件的觀察值
而要從中隨機抽出control組其中一筆作為case組配對結果,即作為一對一簡單配對的動作

其方法則要借用到SQL的模糊比對
在SAS中有類似TSQL語法的 PROC SQL程序
其步驟如下


data case;
input id name$ sex age BMI;
cards;
1 a 1 20 20
2 b 1 21 20
3 c 1 22 21
4 d 1 23 21
5 e 1 24 22
6 f 2 25 22
7 g 2 26 23
8 h 2 27 23
9 i 2 28 24
10 j 2 29 24
;
run;

data control;
input id name$ sex age BMI;
randseed=uniform(0);
cards;
1 c1 2 29 24
2 c2 2 28 24
3 c3 2 27 20
4 c4 2 26 20
5 c5 2 25 21
6 c6 1 20 22
7 c7 1 21 21
8 c8 1 22 22
9 c9 1 23 23
10 c10 1 24 23
;
run;

上述語法中先給Control組每個觀察值一個隨機號碼即亂數randseed,其值0~1。
亂數子的用法uniform(seed)
其實是執行一組符合均值分布的亂數產生器(the Uniform Random Number Generator)
seed則是亂數用到的亂數子可以隨意給定,其值為0到2^31-1之間

另有其他分布的亂數產生器可以用,如Ranbin(seed,n,p)、Rancau(seed)等
可參考如下


本次所要做的則是給定每個觀察值機會均等,所以使用uniform(0),seed則給0。

在給予亂數後
每個觀察值就有亂數之變項randseed可以取用,接下來則是透過配對結果如先前說到,每個Case組有不止一筆Control資料,取每一組Case組配對的Control組其亂數最小作為Case組配對一次的對象。

在給予每筆觀察值後
首先先利用SQL語法達到配對效果
語法如下

data case;
input id name$ sex age BMI;
randseed=uniform(0);
cards;
1 a 1 20 20
2 b 1 21 20
3 c 1 22 21
4 d 1 23 21
5 e 1 24 22
6 f 2 25 22
7 g 2 26 23
8 h 2 27 23
9 i 2 28 24
10 j 2 29 24
;
run;

data control;
input id name$ sex age BMI;
randseed=uniform(0);
cards;
1 c1 2 29 24
2 c2 2 28 24
3 c3 2 27 20
4 c4 2 26 20
5 c5 2 25 21
6 c6 1 20 22
7 c7 1 21 21
8 c8 1 22 22
9 c9 1 23 23
10 c10 1 24 23
;
run;


proc sql;
create table match as
select
case.id as case_id ,
case.name as case_name ,
case.sex as case_sex ,
case.age as case_age ,
case.BMI as case_BMI ,
case.randseed as case_randseed ,
control.id as control_id ,
control.name as control_name ,
control.sex as control_sex ,
control.age as control_age ,
control.BMI as control_BMI ,
control.randseed as control_randseed
from case , control
where case.sex = control.sex;
run;
quit;


上述SQL語法模糊配對的方式在於where case.sex = control.sex;
其實只是告知電腦你要找Case組與Control組條件在於性別相等時成立的結果
即口語上的哪裡是(where)Case組sex等於Control組sex的結果。
若有其他配對條件時也是在這裡執行,如要配對性別及年齡時,可以改為
where case.sex = control.sex and case.age = control.age


SQL檢索完成後之資料轉存到WORK資料夾的MATCH檔。
其結果如下圖(與前述提到每一筆Case組對應到Control組時的狀態)



完成條件檢索後需要進一步篩選每筆Case組只要一筆Control組,達到一對一配對,
其簡單方式則是把Case組取為原觀察數並且選擇Case組亂數最小或最大的保留
即一比一簡單配對方式
方式如下

proc sort data=match; by case_id control_randseed;
data One_TO_One;
set match ; by case_id ;
firstid=first.case_id;
lastid=last.case_id;
if firstid=1 and (lastid=0 or lastid=1) ;
run;

上述語法則是利用系統內設值first last,
若要了解SAS內設語法請自行查詢SAS的Help檔。
其用法是將Case組每一筆觀察值在SQL檢索後產生的重複資料整理為原來的筆數,並且保留了Control組亂數最小的那一筆。
若要一對二配對 另有比較偷懶的方式,就是重複資料取第一筆與最後一筆。



整體結果就是一對一的簡單配對






若要做其他配對方式只要照幾個原則便容易很多
1.觀察值先建立亂數
2.利用SQL語法中where的條件指令做模糊比對
3.根據需求如何取回現有的觀察值及觀察值的配對數目


上述除了能做群體配對與個體配對外
若只想從對照組隨機抽取
可以嘗試使用 PROC SURVEYSELECT 語法

2 則留言:

蔡宗宗 提到...

版大你好

最近拜讀你的文章

真的深入淺出,但我有發現個問題,

可否請版大撥空指點

就是我依你的程式稍做修正為我所需要的情境

但發現control組中卻有被重覆取樣的問題;如

此最後就無法是真的是1:1配對了

可否請妳指點如何不要重複抽樣

萬分謝謝

Kingbee 提到...

時間已久 且我也轉換跑道了.....自廢了

電腦語言是死板的
你可以針對control的資料創新的變項
在配對後就把以配對到的排出

試試看摟.......