本日介紹的是大批資料的匯出,且供資訊人員作為資料庫使用,若搭配網站的架設與資料查詢頁面的製作,即可完成特定資料庫的查詢網站。

為示範程式語法與說明結果,資料為範例資料,請勿引用統計結果或作其他延伸 !!

 

[任務說明]

先說明今日要完成的任務,資料匯出前,有10年的資料,包括20032012年,且有25個縣市別,為提供日後資訊人員建置資料庫,將產生250個資料檔,若再分性別,包括男性、女性、男女合計,將產生750個檔,若結合SAS的巨集指令(MACRO LANGUAGE)ODS(OUTPUT DELIVERY SYSTEM),再將資料轉為HTML格式,將節省表格產出的時間,而HTML的表格自網站下載後,可直接貼至EXCEL中,再作後續的使用。以下要完成的任務條列如下:

1. 輸出的表格必須有表頭(TITLE),表頭需包括(1)年份、(2)縣市別代碼、(3)縣市別,以及(4)表格內容說明。

2. 清楚的變項中文說明

3. 註解要清楚明確, 其中[1] 要說明(1)年份、(2)縣市別代碼、(3)縣市別,以及(4)每年的死亡人數。

4. 表格、表頭與註解要左靠

 

下表為250張表的其中一張。表中框在紅框框裡的項目是將隨(1)年份、(2)縣市別代碼、(3)縣市別,以及(4)每年的死亡人數而變動的項目,我們可以將250種狀況對應成一個編號,利用編號產生外部迴圈,每一個迴圈所代表的(1)年份、(2)縣市別代碼、(3)縣市別,以及(4)每年的死亡人數是不一樣的。但是究竟要如何完成呢?

 

SAS_HTML

[範例資料檔說明]

以癌症死亡資料進行資料處理與統計分析,匯出前的SUMMARY DATA(整理過的資料)有幾個欄位,包括:

1. 死亡時年份,變項名稱為DEATH_YEAR,有10年的資料,包括20032012

2. 25個縣市別代碼,變項名稱為county,包括0125

3. 25個縣市別,變項名稱為county_c,為各縣市的中文名稱 

4.CANCER_C(癌症分類)

5. n_death(死於癌症人數)

6.p_death(死於癌症比例(%))

7.duration_month(癌症發生至死亡時間()) 

 

[程式一]

利用範例資料檔source計算每年各縣市的死亡人口數,以proc freqtables指令計算,並將結果存成num,以death_year, county, county_c分層計算,求得之統計量即為每年之死亡人數(count),因此檔案num中即包含以上所提之(1)年份、(2)縣市別代碼、(3)縣市別,以及(4)每年的死亡人數。最後再以no+1指令產生no變項,no即為外部迴圈所對應之編號,每一編號即一種年份、縣市別、年份等條件。

 

proc freq data=source noprint;

        tables death_year*county*county_c/out=num(keep=death_year county county_c);

run;

data num;

        set num;

              no+1;

proc print data=num;

run;

 

[程式二]

death_1是資料檔source經過一連串的資料處理與統計分析後所產生的資料檔,為了輸出至HTML檔後,要有清楚的變項中文說明,則以label指令對變項名稱作註解,以retain指令指定輸出欄位由左至右之順序,經過處理後的資料檔為death_2

 

data death_2;

         retain CASITE_C
                    n_death p_death
                    du_month;
         set death_1;
               label 
               CANCER_C='癌症分類'
               n_death='死於癌症人數'
               p_death='死於癌症比例(%)'
               duration_month='癌症發生至死亡時間()';
run;

 

[程式三]

將包含(1)年份、(2)縣市別代碼、(3)縣市別、(4)每年的死亡人數以及(5)no (即外部迴圈所對應之編號)之資料檔num合併至包含(1)CANCER_C(癌症分類)(2)n_death(死於癌症人數)(3)p_death(死於癌症比例(%))(4)duration_month(癌症發生至死亡時間())4個變項的資料檔death_2,事實上該檔還包含death_year(死亡年)、縣市別代碼(county)

 

以下所使用的合併指令為merge,合併前要針對兩檔的關鍵變項(key variable)進行排序,關鍵變項為death_year(死亡年)、縣市別代碼(county)

proc sort data=num;
        by death_year county;
proc sort data=death_2;
        by death_year county;
data death_3;
        merge death_2 num;
                    by death_year county;
run;

 

[程式四]

以下為主要的匯出程式,目的為將10年的資料(包括20032012),且有25個縣市別的癌症死亡人數、死亡比例與癌症發生至死亡時間()資料匯出,整批匯出250個資料檔。

步驟如下:

1. 建立巨集名稱(MACRO NAME)與參數(PARAMETER)

    此例建立的MACRO NAMEDATA,內含3個參數,包含x, source, source1,以%macro宣告將即執行巨集指令,程式為%macro data(x,source,source1);

2. 寫一串文字,說明註解1的資料年份、縣市代碼、縣市別、以及該年該縣市的全部死亡人數,程式為

  text='1'||trim(left(death_year))||'年「'||trim(left(county))||' '||trim(county_c)||'」死亡人數:'||trim(left(count))||'人。'; 

'||' 為聯結符號(Concatenate),將資料年份、縣市代碼、縣市別、該年該縣市的全部死亡人數,以及相關文字與符號串聯起來。

trim()為截尾函數,目的將資料後面的空白去除。

left()為左靠函數,目的將數值資料左靠,數值型資料在資料處理軟體中一般為右靠,在此例中,需左靠才不會在一串文字中出現空白。

3. 寫一串文字,說明表格抬頭的內容,其中年份、縣市代碼、縣市別會隨外部迴圈變動,程式為

     text1=trim(left(death_year))||'年「'||trim(left(county))||' '||trim(county_c)||'」死於癌症之分佈'; 

    這段文字也可作為之後匯出HTML時的檔名。

4. 定義參數SOURCE, SOURCE1中的250個參數,分別為VAR1~VAR250VARX1~VARX250,程式為

              source='var'||trim(left(no)); 
              source1='varx'||trim(left(no)); 

5. call symput( )將參數SOURCETEXT關聯起來,當SOURCE被解開,SOURCE對應到VAR1~VAR250250個參數,當VAR1~VAR250也被解開TEXT對應到250個狀況,若外部迴圈的參數x指向 1TEXT對應到VAR1,當VAR1被解開,各變項所對應的內容如後:DEATH_YEAR=2003COUNTY='01'COUNTY_C='○○', COUNT(死亡人數)=2037,程式為

                 call symput('source',text);

6.  call symput( )將參數SOURCE1TEXT1關聯起來,當SOURCE1被解開,SOURCE1對應到VARX1~VARX250250個參數,當VARX1~VARX250也被解開TEXT1對應到250個狀況,若外部迴圈的參數x指向 1TEXT1對應到VARX1,當VARX1被解開,各變項所對應的內容如後:DEATH_YEAR=2003COUNTY='01'COUNTY_C='○○',程式為

            call symput('source1',text1);

步驟1~6完之整程式如下:

%macro data(x,source,source1);


data _null_;
        set num; 
              text='1'||trim(left(death_year))||'年「'||trim(left(county))||''||trim(county_c)||'」死亡人數:'||trim(left(count))||'人。'; 
              text1=trim(left(death_year))||'年「'||trim(left(county))||' '||trim(county_c)||'」死於癌症之分佈'; 
              if no=&x;
              source='var'||trim(left(no)); 
              source1='varx'||trim(left(no)); 
              call symput('source',text);
              call symput('source1',text1);
run;

 

[程式五] 

7. options nocenter 指令指定輸出報表左靠,因此整張表將左靠。

8. ods html style=sasweb指令指定輸出樣式。

9. ods html file="l:\&&source1..html" 指令指定輸出的HTML檔之檔名與路徑。

10. where no=&x指令指定輸出第幾個條件的HTML檔,其中x是巨集參數,扮演的角色是外部迴圈之隨機變數的功能,它的數值來自no,因為x是巨集參數,並非一般變數,因此在參數前加上"&"以示區隔。

11. title j=left "&&source1"指令指定輸出表格之抬頭。如前所述,source1是巨集參數,因此前面要加"&"以示區隔,但在此卻加上了2"&"符號,其目的是為了將source1解開2次,第一次解開對應到varx1~varx250,而varx1~varX250亦是巨集參數,因此仍需被解開,一旦被解開則對應TEXT1上的250種條件,當VARX1被解開TEXT1的文字被對應成

 

2003年「01 ○○縣」死於癌症之分佈

 

12. footnote1 j=left color=black "&&source"指令指定輸出表格輸出之註解1。如前所述,source是巨集參數,因此前面要加"&"以示區隔,但在此卻加上了2"&"符號,其目的是為了將source解開2次,第一次解開對應到var1~var250,而var1~var250亦是巨集參數,因此仍需被解開,一旦被解開則對應TEXT上的250種條件,當VAR1被解開TEXT的文字被對應成

12003年「01 ○○縣」死亡人數:2037人。

 

13. ods html close指令指定輸出的指令到此為止。

 

步驟7~13完之整程式如下:

options nocenter;

ods html style=sasweb;
ods html file="l:\&&source1..html" ;
proc print label data=ll3 noobs;
var CANCER_C
       n_death p_death
       du_month;
       where no=&x;
run;
title j=left "&&source1";
footnote1 j=left color=black "&&source";
footnote2 j=left color=black "2:癌症的定義為原發部位癌,續發部位癌或不詳者不列入。";
footnote3 j=left color=black "3:死於癌症比例(%): 發生癌症者中,死於癌症的比例。";

ods html close;

 

[程式六]

14. %mend指令說明巨集指令包覆的語法到此為止。

15. %macro loop以下的語法又自成一個巨集指令,目的在於產生外部迴圈,MACRO NAMELOOP%DOEND%為以參數X所產生的外部迴圈,其值由1250

%mend;
          %macro loop;
                        %do x=1 %to 250;
                                %data(&x);
                        %end;
          %mend;
          %loop

16. title footnote中的j=left指定將抬頭與註解左靠,color=black指定文字的顏色。

 

資料輸出狀況很多,對於複雜的巨集指令只能熟能生巧,不斷嘗試錯誤,忍受挫折,才能不斷進步,加油吧! 

 

arrow
arrow
    創作者介紹
    創作者 estat 的頭像
    estat

    以斯帖統計顧問公司

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