第 11 章:程式開發

此章節主要介紹 SAS 平台如何開發 SAS 程式碼

基本介紹

SAS 基本介紹

SAS 發展歷史

SAS 最早是由北卡羅來納大學的兩位生物統計學研究生所開發的統計分析系統 (Statistics Analysis System,SAS),首先在 1972 年開發出第一版,接著在 1976 年成立了 SAS 軟體研究所,同時推出了 SAS 軟體,主要是應用於資料分析,其中統計分析功能是最重要組成的核心功能,目前版本為 9.4。

SAS 應用模組

SAS 有許多功能模組,最常見的為 SAS BASE 基礎模組、SAS/STAT 統計分析模組、SAS/GRAPH 繪圖模組、SAS/ACCESS 存取外部資料模組、SAS/CONNECT 分散式資料處理模組、SAS/EM 企業級資料探勘模組、…等。

SAS 基本操作

撰寫程式

我們首先開啟「SAS Base 9.4 (中文(繁體))」軟體,接著在「檔案總管」中點選「資料館」,其中主要有三個重要的資料館必須了解,分別為:

  1. Sasuser:主要為 SAS 使用者個設定相關資訊檔案,永久儲存。

  2. Sashelp:主要為 SAS 範本資料集和協助系統檔案,永久儲存。

  3. Work:主要為資料集的臨時檔案,當退出 SAS 系統時就會被自動刪除

再來在「編輯器」中透過 SAS 範本資料集撰寫下述 SAS 程式。

DATA retail;
  SET sashelp.retail;
RUN;
PROC PRINT;
RUN;

執行程式

接著按下功能表中「黑色小人」進行「提交」作業,此時就會在「日誌」中顯示以下資訊。

1   DATA retail;
2     SET sashelp.retail;
3   RUN;

NOTE: 已從資料集 SASHELP.RETAIL. 讀取 58 個觀測值
NOTE: 資料集 WORK.RETAIL 有 58 個觀測值和 5 個變數。
NOTE: 已使用 DATA 陳述式 (總處理時間):
      實際時間 0.64 秒
      CPU 時間 0.09 秒

4   PROC PRINT;
NOTE: 正在寫入 HTML Body (本文) 檔案: sashtml.htm
5   RUN;

NOTE: 已從資料集 WORK.NEWDATA. 讀取 58 個觀測值
NOTE: 已使用 PROCEDURE PRINT (總處理時間)
      實際時間 2.51 秒
      CPU 時間 0.81 秒

此外還能在「結果檢視器」中看到下表結果。(註:總共 58 筆資料,但下表僅先示意 1980 年的資料。)

Obs

SALES

DATE

YEAR

MONTH

DAY

1

$200

80Q1

1980

1

1

2

$257

80Q2

1980

4

1

3

$258

80Q3

1980

7

1

4

$295

80Q4

1980

10

1

在上述範例中我們主要是建立新的資料集為 WORK.retail,資料來自於資料館中 SASHELP.retail 資料集,其中 WORK 為資料館,而 RETAIL 為資料集,所以我們可以透過「資料館」在 WORK 中找到 RETAIL 資料集。

SAS 資料集

基本介紹

在 SAS 系統中資料主要是以資料集的方式儲存和處理。其實 SAS 資料集可以看成由多行列所組成的表格,其中每一行稱為觀測值,每一列稱為變數,此外我們主要會透過 SAS 邏輯名稱使用 SAS 資料集,不需知道它儲存在哪個資料夾中,若想知道就搜尋 「.sas7bdat」副檔名的檔案就是 SAS 資料集。

命名規則

  1. SAS 名稱最多使用 32 個字元,大小寫字母不區分。

  2. SAS 名稱必須由英文字母、數字、底線所組成,並且第一個字元必須為字母或底線。

  3. SAS 名稱中不能有空格和一些特殊字元,像是%$!*&#@。

SAS 基本結構

SAS 的基本結構主要可以分成二大部份,分別為 DATA SETP 和 PROC STEP。

DATA STEP

當我們要針對資料進行分析時,首先需要建立資料,此時就會透過 DATA STEP 轉換成所需要的資料集,其敘述式主要是以 DATA 敘述開始,下述 SAS 程式就是建立 newdata 的資料集的操作。

DATA retail;
  SET sashelp.retail;
RUN;

PROC STEP

當我們準備好資料集,接著需要針對資料進行分析時,就會根據 DATA STEP 所建立完成的資料集進行統計分析或列印報表,其敘述式主要是以 PROC 敘述開始,下述 SAS 程式就是列印報表的操作。

PROC PRINT;
RUN;

輸入資料

CARDS 換行輸入

上述的範例主要是從資料館中讀取範例資料,但是我們能不能夠自行輸入所需的資料呢?此時我們就會使用到 INPUT 和 CARDS; 關鍵字,請參考下述 SAS 程式。

DATA retail;
INPUT  sales date $ year month day;
CARDS;
550 106Q1 2017 1 1
570 106Q2 2017 4 1
560 106Q3 2017 7 1
530 106Q3 2017 10 1
;
RUN;

第一行 DATA retail 主要是宣告一個資料集稱為 retail,預設儲存在 WORK 資料館中,第二行 INPUT 敘述主要是代表資料欄位,我們主要會宣告四個欄位,當欄位為文字時記得在欄位後方加上 $ 號,第三行 CARDS; 敘述主要是代表下一行準備要輸入資料,也就是說從下一行開始每一行就是一筆資料,輸入完成之後請以 ; 號做結束。

CARDS 不換行輸入

除此之外,我也可以以在 INPUT 敘述最後方加上 @@ 代表連續輸入資料,此時每筆資料就可以不必透過換行區分,請參考下述 SAS 程式。

DATA retail;
INPUT  sales date $ year month day @@;
CARDS;
550 106Q1 2017 1 1 570 106Q2 2017 4 1 560 106Q3 2017 7 1 530 106Q4 2017 10 1
;
RUN;

處理資料

算術運算

若我們所擁有的零售銷售業績,主要是以美元為主的「sales」欄位資料,但長官卻想要知道台幣金額時,就會需要針對資料進行美元轉換台幣的處理。此時我們就可以透過算術運算針對欄位進行處理,請參考下述 SAS 程式。

DATA drv_retail;
  SET retail;
    sales_twd = sales * 30.3195682;
RUN;

算術運算

功能

+

數值相加

-

數值相減

*

數值相乘

/

數值相除

**

數值次方

文字函數

若我們擁有「106Q1」的「date」欄位資料,此時為了比較每一年同季的零售銷售業績,此時建議先轉換出「quarter」欄位資料,以利進行比較分析,請參考下述 SAS 程式。

DATA drv_retail;
  SET retail;
    sales_twd = sales * 30.3195682;
    quarter = substr(date,5,1);
RUN;

文字函數

功能

INDEX(文字一,文字二)

回傳文字二出現在文字一中的位置,若文字二不在文字一中則回傳 0。

SCAN(文字,N,分隔符號)

回傳文字中以分隔符號分割第 N 部份的文字,若分隔符號不指定則預設為空隔. < ( + & ! $ * ) ; ^ - / , % 等分隔符號。

SUBSTR(文字,開始,長度)

回傳變數文字中開始長度的文字,若長度省略則回傳開始之後的所有文字。

TRIM(文字)

回傳刪除文字空白。

UPCASE(文字)

回傳所有文字大寫。

LOWCASE(文字)

回傳所有文字小寫。

LENGTH(文字)

回傳文字長度,不考慮最後空白。

CAT(文字一,文字二,…)

回傳文字的連接,主要會留下頭尾空白。

CATS(文字一,文字二,…)

回傳文字的連接,主要會刪除頭尾空白。

CATX(符號字元,文字一,文字二,…)

回傳文字的連接,主要會留下頭尾空白,並且用指定的符號字元連接。

TRANWRD(文字,文字一,文字二)

回傳文字中的文字二取代文字一。

輸出資料

最近處理資料集

當我們透過 DATA STEP 完成資料處理之後,就能夠透過 PROC STEP 輸出資料,其實 PROC 代表 Procedure,也就是程序或函數,因此我們會透過 PRINT 程序列印最後一次處理的資料集,請參考下述 SAS 程式。

PROC PRINT;
RUN;

指定處理資料集

此外我們也可以加入 DATA 參數指定處理資料集,請參考下述 SAS 程式。

PROC PRINT DATA=work.drv_retail;
RUN;

分析資料

呈現統計資訊

當我們輸出資料確認資料無誤之後,下一步就是進行分析資料,一般來說,只須要透過 UNIVARIATE 程序就能夠針對變數匯整出動差、基本統計量值、位置檢定、分位數和極端觀測值等統計資訊,以利分析資料,其中基本統計量值就是我們常常提到平均值、中位數、眾數、標準差、變異數、全距和內四分位距等資訊,請參考下述 SAS 程式。

PROC UNIVARIATE DATA=work.drv_retail;
RUN;

匯出統計資訊

除此之外,我們也可以透過 UNIVARIATE 程序指定要匯出的特定統計資訊至特定資料集中,例如我們僅想針對零售銷售業績的平均值和標準差匯出為報告資料集,請參考下述 SAS 程式。

PROC UNIVARIATE DATA=work.drv_retail;
  OUTPUT OUT=work.retail_report MEANS=sales_twd_means STD=sales_twd_std;
RUN;
PROC PRINT DATA=work.retail_report;
RUN;

總結我們首先從開啟「 SAS Base 9.4 (中文(繁體)) 」軟體使用預設 RETAIL 範例資料集撰寫 DATA STEP 和 PROC STEP 程式的基本操作開始,接著透過撰寫 DATA STEP 程式進行輸入資料和處理資料,最後透過撰寫 PROC STEP 程式進行輸出資料和分析資料。因此 SAS 程式的兩大重點在於 DATA STEP 和 PROC STEP 的操作,至於更深入的操作則差別在於參數的不同而已,至於 SAS 語法基本上皆大同小異。

整合應用

首先在 SAS Viya 平台中我們可以透過 SAS Studio V 撰寫 SAS 程式碼,接著透過 SAS Job Execution 網站進行 SAS 程式碼的排程工作,相較於 SAS 9 平台主要是以 Workspace Server 伺服器執行 SAS 程式碼,而在 SAS Viya 平台則是以 Compute Server 伺服器執行 SAS 程式碼,至於 SAS 9 和 SAS Viya 平台的差別,請參考下表。

SAS 9

SAS Viya

Object Spawner

Launcher Server + Service

Workspace Server

Compute Server + Service

SAS Foundation

Programming Runtime Environment (SPRE)

接著我們可以透過 SAS Job Execution 新增工作定義檔案,請注意 SAS Job Execution 必須透過網址 (https:// [SAS Viya 主機名稱] /SASJobExecution) 開啟,預設無法透過 SAS Viya 網站中的功能表開啟,之後我們需要按照以下步驟進行 SAS 程式碼的排程工作,分別為:

  1. 在 SAS Studio V 中撰寫和複製 SAS 程式碼。

  2. 在 SAS Job Execution 中建立和貼上 SAS 程式碼。

  3. 在 SAS Environment Manager 中建立排程工作。

再來目前若以 SAS Viya 平台排定特定時間執行 SAS Job Execution 中的 SAS 程式碼,但是還無法設定多個 SAS 程式碼的相依關係。但是我們則可以在工作定義中撰寫以下 SAS 程式碼,以利按照順序執行 SAS 程式碼,以及更能透過 &sysrc 等系統回傳值判斷 SAS 程式碼是否正常執行,請注意工作定義中不能夠只用「CAS CASAUTO;」,不然會發生「The request to start or connect to a session failed. Specify a UUID to connect to an existing session or specify a session name, port and host name to start a session.」錯誤訊息。

工作定義 SAS 程式碼

cas casauto host='<SAS Viya 主機名稱>' port=5570 sessopts=(caslib=Public timout=1000 locale="en_US");
filename <工作排程名稱> FILESRVC folderpath='<SAS 程式碼資料夾>' filename='<SAS 程式碼檔案名稱>';
%include <工作排程名稱> / source;
%put &syscc rc=&sysrc &syserr &syserrortext &syswarningtext;

儲存資料 SAS 程式碼

cas auto;
libname mycas cas caslib=casuser;      
data mycas.cars;
   set sashelp.cars;
run;
proc casutil  incaslib="casuser" outcaslib="casuser";    
   save casdata="cars" replace; 
run;  
proc casutil;    
   droptable casdata="cars" incaslib="casuser"; 
run;  
cas terminate;

儲存資料 SAS 程式碼 (巨集)

/* %exportFile(SAS 9 資料集, CAS 資料館, SASHDAT 檔案名稱) */
%macro exportFile(v_sasdata,v_caslib,v_casdata);
cas auto;
libname viyacas cas caslib=&v_caslib;                      
data viyacas.&v_casdata;
   set &v_sasdata;
run;
proc casutil incaslib="&&v_caslib" outcaslib="&&v_caslib";    
   save casdata="&&v_casdata" replace; 
run;  
proc casutil;    
   droptable casdata="&&v_casdata" incaslib="&&v_caslib"; 
run;  
cas terminate;
%mend;

%exportFile(sashelp.cars,casuser,cars);

當我們在 SAS Job Execution 新增完成工作定義之後,在工作定義上按右鍵選取「提交工作」就能夠立即執行工作,請注意每次提交工作系統就會在 SAS Environment Manager 中自動建立工作排程,以利後續設定時間定期執行。

最後當我們透過 SAS Job Execution 執行工作時預設則是會以「cas」系統帳號進行作業系統層的檔案存取操作,若是期望以該執行排程工作的使用者帳號進行檔案存取操作,則需要先建立「CASHostAccountRequired」群組,並且將該使用者帳號加入至該群組中,並且重新登出和登入 SAS Viya 平台,再執行工作排程就能夠以該使用者帳號進行檔案存取操作。

開始使用

  • 登入至 SAS Viya 分析平台。

  • 在畫面左上方點選【顯示應用程式功能表】鈕。

  • 選取【開發 SAS 程式碼】。

  • 開始撰寫 SAS 程式碼。

  • 輸入以下 SAS 程式碼,按下【提交】鈕。

libname mycaslib cas;
  • 完成 MYCASLIB 資料館的建立,選取【資料館】頁籤。

  • 點選【MYCASLIB】,在【HMEQ】資料上按右鍵點選【開啟】,以確認資料內容。

  • 選取【工作】頁籤。

  • 展開【SAS 工作】。

  • 展開【SAS Viya 監督式學習】。

  • 點選【決策樹】,按下右鍵點選【開啟】。

  • 點選【選取表格】鈕。

  • 點選【MYCASLIB】資料館中的【HMEQ】資料集,按下【確定】鈕。

  • 在【名目目標】的【增加變數】上按下左鍵。

  • 點選【BAD】。

  • 在【間隔輸入】的【增加數值變數】上按下左鍵。

  • 勾選所有項目,總共 10 個輸入變數為【間隔輸入】,按下【確定】鈕。

  • 在【名目輸入】的【增加變數】上按下左鍵。

  • 勾選所有項目,總共 2 個輸入變數為【名目輸入】,按下【確定】鈕。

  • 按下【提交】鈕。

  • 按下【更多】鈕。

  • 點選【最大化預覽窗格】。

  • 點選【概觀】,查看【BAD 的分類決策樹】的概觀。

  • 點選【配適統計值】查看【配適統計值】,以及點選【變數重要性】查看【變數重要性】。

  • 選取【程式碼】頁籤,查看自動產生的【SAS 程式碼】。

/* 
 * 
 * SAS® Studio 5.1
 *  產生的工作代碼
 * 產生時間 '2019/9/16 上午2:56'
 * 產生者 'leoyeh.me@gmail.com'
 * 產生於伺服器 'sasserver'
 * 產生於 SAS 平台 'Linux LIN X64 2.6.32-696.18.7.el6.x86_64'
 * 產生於 SAS 版本 'V.03.04M0P050819'
 * 產生於瀏覽器 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
 * 產生於 Web 用戶端 'https://pdcesx20095.sas.com/SASStudioV/main?locale=zh_TW&launchedFromAppSwitcher=true'
 */

ods noproctitle;

proc treesplit data=MYCASLIB.HMEQ maxdepth=10;
	input LOAN MORTDUE VALUE YOJ DEROG DELINQ CLAGE NINQ CLNO DEBTINC / 
		level=interval;
	input REASON JOB / level=nominal;
	target BAD / level=nominal;
	grow igr;
	prune none;
run;
  • 按下【儲存】鈕。

  • 選取【SAS 內容】->【Users】->【<電子郵件帳號>】->【My Folder】->【資料分析專案】,修改【名稱】為【HMEQ 決策樹】,按下【儲存】鈕。

  • 按下【另存新檔】鈕。

  • 選取【類型】為【程式 (*.sas)】,按下【儲存】鈕。

Last updated