過去已介紹檔案間沒有關鍵字將如何合併?(資料的合併)利用該程式,今日要教各位如何讀取大批命名有規律的檔。

自「全民健康保險研究資料庫」釋出後,大型資料的研究已是台灣學術研究的優勢,在國際學術期刊上已有亮麗成績,「衛生福利資料科學中心」如今亦開放健保資料庫、癌症登記檔與死亡檔的資料比對,但面對全國性的龐大資料檔,光是讀檔案的步驟,就是惱人的大工程。不用著急,也毋需土法煉鋼,今天的程式可以讓大家以後讀檔更輕鬆了。

以下將以讀取「衛生福利資料科學中心」之健保民國87-99年「門診處方及治療明細檔」為例,其中一個檔名為h_nhi_opdte8702_01。如何拆解這個檔名呢?h_nhi_opdte 在龐大的檔案群是固定的87為年份,02為月份,01為西醫(0203為牙醫與中醫),因此所有檔案讀進來,一年有36個檔13年有468個檔,如何讀取這麼龐大的檔案群呢?

[程式一] 利用程式寫入3個資料檔,第一個資料檔檔名為year,僅放入民國年資料;第二個資料檔檔名為month,僅放入月份資料;第三個資料檔檔名為group,僅放入醫療型態(西醫、牙醫、中醫)資料。


[
程式一]
data year;
input year $ @@;
cards;
87 88 89 90 91 92 93 94 95 96 97 98 99
;
run;

data month ;
input month $ @@;
cards;
01 02 03 04 05 06 07 08 09 10 11 12
;
run;

data group;
input group $ @@;
cards;
01 02 03
;
run;


將檔案建立後,利用SQL(結構式查詢語言)程式可以將三個沒有關鍵字的檔案合併起來,檔名為ym產生468筆資料檔。[見程式二]

[程式二]
proc sql;
create table ym as
select *
from year, month,group;
quit;


利用累加語法no+1,將每一筆資料編上1~468的流水號。其中,no的起始值(initial)0,第一筆資料即為0+1=1,接下來依序為1+12+13+1…,每一個編號對應至一個年份、月份與醫療型態(西醫、牙醫、中醫)。若能將這些複雜的檔名讀取後,並轉為流水號型式的檔案,每當要取用資料檔時,就可以輕易用迴圈讀取了,在資料合併的過程,也變得相當簡單。例如以迴圈從468個檔擷取所要的特定疾病,新的資料檔的檔名為cd1-cd468再以set cd1-cd468;語法將這468個檔案合併起來,而得到13年間所有研究所關心的特定疾病。  [見程式三]

[程式三]
data aa;
set ym;
no+1;
run;

[結果]                                              

                                    Obs    year    month    group    no

                                                 1       87         01        01        1
                                                 2       87         02        01        2
                                                 3       87         03        01        3
                                                 4       87         04        01        4
                                                 5       87         05        01        5
                                                 6       87         06        01        6
                                                 7       87         07        01        7
                                                 8       87         08        01        8
                                                 9       87         09        01        9
                                                10       87        10        01       10
                                                11       87        11        01       11
                                                12       87        12        01       12
                                                13       87        01        02       13
                                                14       87        02        02       14
                                                15       87        03        02       15
                                                16       87        04        02       16
                                                17       87        05        02       17
                                                18       87        06        02       18
                                                19       87        07        02       19
                                                20       87        08        02       20
                                                21       87        09        02       21
                                                22       87        10        02       22
                                                23       87        11        02       23
                                                24       87        12        02       24
                                                25       87        01        03       25
                                                26       87        02        03       26
                                                27       87        03        03       27
                                                28       87        04        03       28
                                                29       87        05        03       29
                                                30       87        06        03       30

 

                                                          (no=31~468省略)

 

為什麼要找出檔案命名的規則呢?因為您若不找到這規則,要手工更468次檔案名稱,才能將檔案讀取進來,而且可能一個不小心而改錯,自己也不自知,因此資料的正確性只有天知!!

[程式四]~[程式七]在語法上稱為MACRO LANGUAGE(巨集指令),它可透過產生迴圈的方式控制主要程式的運作 ,如[程式六]為研究者的主要資料處理步驟,但因相同的處理步驟會在多達468個檔案中反覆執行,這個反覆的過程唯二會改變的包DATA 之後的新檔案的建立,以及SET後面所要讀取的468個檔。中間省略的<請自行填入資料處理步驟>通常是以IF條件句擷取特定的研究資料。

由於我們已產生一個由YEAR, MONTH, GROUP所組成的468筆檔案,每一筆代表一個檔案的組成,我們可以將每一種組成對應到一個流水號 no,並形成外部迴圈。以下為每一段程式的講解: 

[程式四]%macro是巨集指令,宣告之後將產生一個巨集變項(macro variable)mv的巨集 ,在這個巨集中有2個參數(parameter)x source,x為隨機變數,與外部迴圈有關;source對應到檔名,在程式中,參數的前面會加上"&"符號,可與SAS的一般名稱作區別

[程式七]%mend是巨集的結束指令,宣告巨集所包覆的主要程式結束於此,並將參數x對應到一組1~468的數值中,產生迴圈。

[程式五]call symput('source',text)是至為關鍵的部份,它將參數source與它最終會被解開的文字串text關聯起來,而這組文字串text='c.h_nhi_opdte'||trim(year)||trim(month)||'_'||trim(group即是468個檔名的歸納式,是由連結符號”||”串連起來的,串連檔名的主要部份[c.h_nhi_opdte]與後面的YEAR, MONTHGROUP,當迴圈讀到x=1時,會對應到no=1 (因為程式中有一段if no=&x 程式),也就是第一筆資料。這時巨集指令會將參數SOURCE解開,SOURCE的對應值是TEXT,當巨集被解開,就會將TEXT解開成c.h_nhi_opdte8701_01,因為填入的值是由if no=1所決定;其它以此類推。

[程式六]DATA的後面是新的檔名,已被命名為cd&x&x是巨集的參數,當迴圈數為1時,新的資料即被命名為CD1;當迴圈數為468時,新的資料即被命名為CD468SET後面所讀取的資料檔為&SOURCE ,被解開時對應到text,當這個參數被解開後就將TEXT中的YEAR, MONTH, GROUP的對應值填入,而輕鬆地讀入468個檔案。

最後透過迴圈將讀入後的新檔案命名為流水號型式,將有利於後續的資料處理。

很難懂是嗎? 巨集確實是語法中較為深奧的部份。

[程式四]
%macro mv(x); 

[
程式五]
data _null_;
set aa;
text='c.h_nhi_opdte'||trim(year)||trim(month)||'_'||trim(group); 
if no=&x then call symput('source',text);
run;


[
程式六]
data e.cd&x;
set &source;
<
請自行填入資料處理步驟>
run;

[
程式七]
%mend;
%macro loop;
%do x=1 %to 468;
%mv(&x);
%end;
%mend;
%loop


 

arrow
arrow

    estat 發表在 痞客邦 留言(1) 人氣()