SAS:数据合并简介
數據合并,即兩個或者多個數據集的數據合并到一個數據集中,常見的方式有3種,分別是 one-to-one reading、concatenating 和 Match-merging,其中只有最后一種Match-merging是要求匹配字段是已經排好序的。
?
在介紹之前,準備兩個基礎數據,是已經按照ID排好序的
cert.patdat
| A001 | 21 | M | 08/17/1997 |
| A002 | 32 | M | 02/18/1986 |
| A003 | 24 | F | 06/07/1994 |
| A004 | 28 | M | 01/27/1990 |
| A005 | 44 | F | 04/24/1974 |
| A007 | 39 | M | 07/10/1979 |
| A008 | 30 | F | 09/16/1988 |
?
cert.visit
| A001 | 1 | 140 | 85 | 195 | 11/05/2009 |
| A001 | 2 | 138 | 90 | 198 | 10/13/2009 |
| A001 | 3 | 145 | 95 | 200 | 07/04/2009 |
| A002 | 1 | 121 | 75 | 168 | 04/14/2009 |
| A003 | 1 | 118 | 68 | 125 | 08/12/2009 |
| A003 | 2 | 112 | 65 | 123 | 08/21/2009 |
| A004 | 1 | 143 | 86 | 204 | 03/30/2009 |
| A005 | 1 | 132 | 76 | 174 | 02/27/2009 |
| A005 | 2 | 132 | 78 | 175 | 07/11/2009 |
| A005 | 3 | 134 | 78 | 176 | 04/16/2009 |
| A008 | 1 | 126 | 80 | 182 | 05/22/2009 |
?
下面分別看一下三種方式
one-to-one reading
工作原理
one-to-one reading?
創建一個新的數據集,新的數據集包含所有的變量。
根據每個觀測在數據集中的位置去匹配,第2個數據集中變量的值會覆蓋第1個數據集中變量的值。
結果集中觀測的數量和數據量較少的那個數據集一樣。
說簡單一點,就是先從第1個數據集拿一行,然后再從第2個數據集拿一行去覆蓋第1個數據集中數據。以次類推,直到有一個數據集結束。
?
語法
DATA output-SAS-data-set;
?SET?SAS-data-set-1;
?SET?SAS-data-set-2;
RUN;
?
示例
libname cert 'J:\sas_guide_data\base-guide-practice-data\cert';data tmp1;set cert.patdat;set cert.visit; run;proc print data=tmp1; run;輸出:
| A001 | 21 | M | 11/05/2009 | 1 | 140 | 85 | 195 |
| A001 | 32 | M | 10/13/2009 | 2 | 138 | 90 | 198 |
| A001 | 24 | F | 07/04/2009 | 3 | 145 | 95 | 200 |
| A002 | 28 | M | 04/14/2009 | 1 | 121 | 75 | 168 |
| A003 | 44 | F | 08/12/2009 | 1 | 118 | 68 | 125 |
| A003 | 39 | M | 08/21/2009 | 2 | 112 | 65 | 123 |
| A004 | 30 | F | 03/30/2009 | 1 | 143 | 86 | 204 |
可以看到,兩個數據集都有的變量ID和Date,結果集中只出現1次,且被第2個數據集的值覆蓋。
當然,上面這個例子沒有實際的意義,下圖中的例子才有實際的意義:
?
concatenating
?
工作原理
concatenating即將兩個數據集連接起來
?
語法
DATA output-SAS-data-set;
?SET?SAS-data-set-1
?? ? ? ??SAS-data-set-2;
RUN;
?
示例
data tmp2;set cert.patdatcert.visit; run;proc print data=tmp2; run;輸出:
| A001 | 21 | M | 08/17/1997 | . | . | . | . |
| A002 | 32 | M | 02/18/1986 | . | . | . | . |
| A003 | 24 | F | 06/07/1994 | . | . | . | . |
| A004 | 28 | M | 01/27/1990 | . | . | . | . |
| A005 | 44 | F | 04/24/1974 | . | . | . | . |
| A007 | 39 | M | 07/10/1979 | . | . | . | . |
| A008 | 30 | F | 09/16/1988 | . | . | . | . |
| A001 | . | ? | 11/05/2009 | 1 | 140 | 85 | 195 |
| A001 | . | ? | 10/13/2009 | 2 | 138 | 90 | 198 |
| A001 | . | ? | 07/04/2009 | 3 | 145 | 95 | 200 |
| A002 | . | ? | 04/14/2009 | 1 | 121 | 75 | 168 |
| A003 | . | ? | 08/12/2009 | 1 | 118 | 68 | 125 |
| A003 | . | ? | 08/21/2009 | 2 | 112 | 65 | 123 |
| A004 | . | ? | 03/30/2009 | 1 | 143 | 86 | 204 |
| A005 | . | ? | 02/27/2009 | 1 | 132 | 76 | 174 |
| A005 | . | ? | 07/11/2009 | 2 | 132 | 78 | 175 |
| A005 | . | ? | 04/16/2009 | 3 | 134 | 78 | 176 |
| A008 | . | ? | 05/22/2009 | 1 | 126 | 80 | 182 |
同樣的,兩個數據集都有的變量ID和Date,只出現一次, 但因為這個是連接,所以不存在值覆蓋問題。
同樣的,上面的例子沒有實際意義,只是為了展示工作原理,下面的例子才有實際意義:
?
Match-merging
工作原理
Match-merging這個就是merge了,按照某個字段的值進行匹配,如果匹配上,就合并到一條記錄中。
?
語法
DATA output-SAS-data-set;
?MERGE?SAS-data-set-1
?? ? ? ? ? ? ??SAS-data-set-2;
?BY <DESCENDING> variable(s);
RUN;
?
示例
data tmp2;merge cert.patdatcert.visit;by id; run;proc print data=tmp2; run;輸出
| A001 | 21 | M | 11/05/2009 | 1 | 140 | 85 | 195 |
| A001 | 21 | M | 10/13/2009 | 2 | 138 | 90 | 198 |
| A001 | 21 | M | 07/04/2009 | 3 | 145 | 95 | 200 |
| A002 | 32 | M | 04/14/2009 | 1 | 121 | 75 | 168 |
| A003 | 24 | F | 08/12/2009 | 1 | 118 | 68 | 125 |
| A003 | 24 | F | 08/21/2009 | 2 | 112 | 65 | 123 |
| A004 | 28 | M | 03/30/2009 | 1 | 143 | 86 | 204 |
| A005 | 44 | F | 02/27/2009 | 1 | 132 | 76 | 174 |
| A005 | 44 | F | 07/11/2009 | 2 | 132 | 78 | 175 |
| A005 | 44 | F | 04/16/2009 | 3 | 134 | 78 | 176 |
| A007 | 39 | M | 07/10/1979 | . | . | . | . |
| A008 | 30 | F | 05/22/2009 | 1 | 126 | 80 | 182 |
可以看到,兩個數據集都有的變量Date,輸出中只出現一次, 且被第2個數據集的值覆蓋(ID是匹配字段,所以談不上覆蓋),這是第一個問題。
另外一個問題是,結果集中的ID是包含了兩個數據集中所有的值,無論是否能匹配上,比如A007只在數據集中patdat中出現過,如果想要結果集中只出現匹配的項怎么辦?
針對這兩個問題,都是有解決方案的。
問題1:patdat和visit中都有Date變量,但兩者的含義并不相同,前者是出生日期,后者是指訪問日期,如何避免被覆蓋?答案是可以使用rename選項,選項語法為(RENAME=(old-variable-name=new-variable-name))
示例:
data tmp2;merge cert.patdat(RENAME=(Date=BirthDate))cert.visit(RENAME=(Date=VisitDate));by id; run;proc print data=tmp2; run;輸出:
| A001 | 21 | M | 08/17/1997 | 1 | 140 | 85 | 195 | 11/05/2009 |
| A001 | 21 | M | 08/17/1997 | 2 | 138 | 90 | 198 | 10/13/2009 |
| A001 | 21 | M | 08/17/1997 | 3 | 145 | 95 | 200 | 07/04/2009 |
| A002 | 32 | M | 02/18/1986 | 1 | 121 | 75 | 168 | 04/14/2009 |
| A003 | 24 | F | 06/07/1994 | 1 | 118 | 68 | 125 | 08/12/2009 |
| A003 | 24 | F | 06/07/1994 | 2 | 112 | 65 | 123 | 08/21/2009 |
| A004 | 28 | M | 01/27/1990 | 1 | 143 | 86 | 204 | 03/30/2009 |
| A005 | 44 | F | 04/24/1974 | 1 | 132 | 76 | 174 | 02/27/2009 |
| A005 | 44 | F | 04/24/1974 | 2 | 132 | 78 | 175 | 07/11/2009 |
| A005 | 44 | F | 04/24/1974 | 3 | 134 | 78 | 176 | 04/16/2009 |
| A007 | 39 | M | 07/10/1979 | . | . | . | . | . |
| A008 | 30 | F | 09/16/1988 | 1 | 126 | 80 | 182 | 05/22/2009 |
可以看到輸出中的BirthDate和VisitDate各占了一個變量
?
問題2:merge的時候如何只顯示真正匹配上的行?
答案是可以使用IN選項,選項語法為IN=variable,它創建一個臨時變量,如果當前觀測對結果集有用,那么該變量值會被設置為1,否則設置為0,在匹配的時候加上IF關健字判斷即可。注:這個變量并不會出現在結果集中。
示例:
data tmp2;merge cert.patdat(IN=tmpvar1 RENAME=(Date=BirthDate))cert.visit(IN=tmpvar2 RENAME=(Date=VisitDate));by id;if tmpvar1 eq 1 AND tmpvar2 eq 1; run;proc print data=tmp2; run;輸出:
| A001 | 21 | M | 08/17/1997 | 1 | 140 | 85 | 195 | 11/05/2009 |
| A001 | 21 | M | 08/17/1997 | 2 | 138 | 90 | 198 | 10/13/2009 |
| A001 | 21 | M | 08/17/1997 | 3 | 145 | 95 | 200 | 07/04/2009 |
| A002 | 32 | M | 02/18/1986 | 1 | 121 | 75 | 168 | 04/14/2009 |
| A003 | 24 | F | 06/07/1994 | 1 | 118 | 68 | 125 | 08/12/2009 |
| A003 | 24 | F | 06/07/1994 | 2 | 112 | 65 | 123 | 08/21/2009 |
| A004 | 28 | M | 01/27/1990 | 1 | 143 | 86 | 204 | 03/30/2009 |
| A005 | 44 | F | 04/24/1974 | 1 | 132 | 76 | 174 | 02/27/2009 |
| A005 | 44 | F | 04/24/1974 | 2 | 132 | 78 | 175 | 07/11/2009 |
| A005 | 44 | F | 04/24/1974 | 3 | 134 | 78 | 176 | 04/16/2009 |
| A008 | 30 | F | 09/16/1988 | 1 | 126 | 80 | 182 | 05/22/2009 |
可以看到,結果集只有11個了。A007沒有匹配上
?
參考資料:
SAS Certified Specialist Prep Guide
?
?
總結
以上是生活随笔為你收集整理的SAS:数据合并简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 测试工程师之【python】按工龄开始日
- 下一篇: 废旧三元锂电池回收提镍钴锰