一、SAS 基礎語法與程式結構
先掌握 SAS 的語句風格,你之後看任何範例都會更容易理解。
1. 程式基本組成
SAS 程式一般由多個步驟組成,最常見的是: DATA Step 用來建立、讀取、清理與轉換資料; PROC Step 用來分析、排序、統計、輸出報表。
data work.mydata;
input id name $ score;
datalines;
1 Amy 85
2 Ben 92
3 Cathy 88
;
run;
proc print data=work.mydata;
run;
2. 每個語句通常以分號結尾
SAS 中幾乎每一行敘述都需要以分號結尾。這是初學者最容易忽略的地方, 少一個分號就可能讓後續整段程式報錯。
libname mylib "C:\sasdata";
options nodate nonumber;
title "學生成績表";
3. 大小寫通常不敏感
多數 SAS 關鍵字不區分大小寫,例如 data、DATA、
Proc Print 在語意上通常都可被辨識。但為了可讀性,建議維持一致風格。
DATA work.demo;
x = 1;
RUN;
proc print data=work.demo;
run;
4. 註解寫法
SAS 常見註解有兩種:
| 註解方式 | 寫法 | 說明 |
|---|---|---|
| 單行註解 | * 這是註解 ; |
以 * 開頭,最後也要加分號 |
| 區塊註解 | /* 這是多行註解 */ |
較適合註解多行內容 |
* 這是一行說明文字 ;
/* 這是一段
多行註解 */
5. 常見保留觀念
WORK:暫存資料庫,程式結束後通常會消失。LIBNAME:指定永久資料庫位置。RUN;:執行目前步驟。QUIT;:結束某些程序,例如PROC SQL。
libname mylib "C:\project\data";
data mylib.sales_2025;
set work.temp_sales;
run;
初學者必背:SAS 最常見骨架範本
/* 1. 指定資料庫位置 */
libname mylib "C:\sas_project\data";
/* 2. 建立或清理資料 */
data work.cleaned_data;
set mylib.raw_data;
if score >= 60 then pass = "Y";
else pass = "N";
run;
/* 3. 分析與輸出 */
proc freq data=work.cleaned_data;
tables pass;
run;
二、DATA Step:建立、讀取與轉換資料
DATA Step 是 SAS 最核心的能力之一。你可以把它想成「資料工程區」:讀資料、改欄位、算新欄位、過濾資料都在這裡完成。
DATA 敘述:定義要建立的資料集
DATA 會告訴 SAS 你要建立哪一個資料集,例如 work.students。
data work.students;
input id name $ score;
datalines;
1 Amy 85
2 Ben 92
3 Cathy 78
;
run;
INPUT 與 DATALINES:手動輸入簡單資料
如果資料筆數很少,或你只是做教學示範,INPUT 搭配 DATALINES 很方便。
注意字串欄位通常要加上 $。
data work.classroom;
input student_id name $ math english;
datalines;
1001 Amy 90 88
1002 Ben 76 81
1003 Cara 95 93
;
run;
SET:從既有資料集讀入資料
當你想要在原始資料上再加工時,會用 SET 把既有資料集讀進來。
data work.classroom2;
set work.classroom;
average = mean(math, english);
run;
IF-THEN/ELSE:建立條件邏輯
SAS 可以在 DATA Step 中做條件判斷,像是分級、標記通過與否、資料清理等。
data work.classroom3;
set work.classroom2;
if average >= 90 then grade = "A";
else if average >= 80 then grade = "B";
else if average >= 70 then grade = "C";
else grade = "D";
run;
常用函數與欄位處理
在 DATA Step 中,你會經常搭配函數來整理資料:
| 函數 | 用途 | 範例 |
|---|---|---|
mean() |
計算平均 | avg = mean(math, english); |
sum() |
加總 | total = sum(q1, q2, q3); |
missing() |
判斷缺失值 | if missing(region) then region="UNKNOWN"; |
substr() |
擷取字串 | area = substr(phone,1,3); |
upcase() |
轉大寫 | name_up = upcase(name); |
日期與格式化
SAS 對日期與格式有強大支援。你可以用 FORMAT 來調整輸出樣式,
用 INFORMAT 或特定讀法來解析輸入資料。
data work.orders;
input order_id order_date : yymmdd10. amount;
format order_date yymmdd10. amount comma10.2;
datalines;
1 2025-01-15 12500.5
2 2025-02-08 3780
3 2025-02-10 9100.25
;
run;
冒號修飾符與日期 informat 常見搭配像是
: yymmdd10.,
輸出時再用 format 控制顯示樣式。
DATA Step 實用練習:清理銷售資料
data work.sales_clean;
set work.sales_raw;
revenue = qty * price;
if missing(region) then region = "UNKNOWN";
if qty < 0 then qty = .; /* 負數視為異常值 */
if revenue >= 100000 then segment = "High";
else if revenue >= 50000 then segment = "Medium";
else segment = "Low";
format revenue comma12.2;
run;
三、PROC Step:分析、排序與報表輸出
當資料整理好之後,SAS 常透過各種 PROC 來完成分析與輸出。
1. PROC PRINT:列出資料內容
這是最常用的查看資料方式,適合檢查資料是否正確讀入或轉換。
proc print data=work.classroom3;
var student_id name math english average grade;
title "班級成績總覽";
run;
2. PROC SORT:排序資料
若你要依某些欄位排序資料,可用 PROC SORT。
之後若要搭配 BY 群組分析,通常也會先排序。
proc sort data=work.classroom3 out=work.classroom_sorted;
by descending average name;
run;
3. PROC MEANS:計算統計摘要
可快速得到筆數、平均、總和、最大值、最小值等統計量。
proc means data=work.classroom3 n mean min max maxdec=2;
var math english average;
run;
4. PROC FREQ:類別次數統計
分析類別型欄位的出現次數、比例或交叉表時很常用。
proc freq data=work.classroom3;
tables grade / nocum;
run;
常見 PROC 用途整理表
| PROC | 用途 | 典型情境 |
|---|---|---|
PROC PRINT |
印出資料列 | 檢查資料內容、做簡單報表 |
PROC SORT |
依欄位排序 | 排序後做 BY 分析 |
PROC MEANS |
數值摘要統計 | 平均數、總和、最大最小值 |
PROC FREQ |
類別頻數統計 | 分類變數分布、交叉表 |
PROC CONTENTS |
查看資料結構 | 確認欄位型態、長度、標籤 |
延伸:先排序,再用 BY 分組分析
proc sort data=work.sales_clean out=work.sales_sorted;
by region;
run;
proc means data=work.sales_sorted n sum mean;
by region;
var revenue;
run;
重點觀念:當你使用 BY region; 時,資料通常需要先依 region 排序。
四、PROC SQL:用 SQL 方式查詢 SAS 資料
如果你熟悉資料庫查詢語法,PROC SQL 會是非常高效率的工具,可以做查詢、彙總、排序、連接資料表等。
SELECT 基本結構
PROC SQL 中最常見的流程是:
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY。
proc sql;
select name, average
from work.classroom3
where average >= 80
order by average desc;
quit;
在
PROC SQL 中,通常使用 QUIT; 結束步驟。
建立新資料表
你可以直接把查詢結果存成新資料表:
proc sql;
create table work.top_students as
select student_id, name, average
from work.classroom3
where average >= 85
order by average desc;
quit;
群組彙總
搭配 group by 與聚合函數,可快速做業務、產品、地區彙整報表。
proc sql;
create table work.region_summary as
select region,
count(*) as order_count,
sum(revenue) as total_revenue format=comma12.2,
mean(revenue) as avg_revenue format=comma12.2
from work.sales_clean
group by region
order by total_revenue desc;
quit;
資料表連接 JOIN
這是 SQL 最常用的能力之一,用來合併主檔與對照表、訂單與客戶資料等。
proc sql;
create table work.order_customer as
select a.order_id,
a.customer_id,
a.amount,
b.customer_name,
b.city
from work.orders as a
left join work.customers as b
on a.customer_id = b.customer_id;
quit;
PROC SQL 與 DATA Step 怎麼選?
| 情境 | 較適合工具 | 原因 |
|---|---|---|
| 逐列計算新欄位 | DATA Step | 欄位轉換與條件邏輯很直觀 |
| 表格彙總查詢 | PROC SQL | GROUP BY / ORDER BY 寫法清楚 |
| 多資料表關聯 | PROC SQL | JOIN 更方便 |
| 複雜逐筆資料清理 | DATA Step | 邏輯判斷與函數控制彈性高 |
五、Macro:把重複工作自動化
SAS Macro Language 常用於產生重複程式碼、批次跑不同參數、建立可重用流程。
Macro 的基本結構
一個 Macro 通常由 %macro 開始,並以 %mend 結束。
%macro hello;
%put Hello SAS Macro!;
%mend;
%hello;
帶參數的 Macro
當你想讓同一段流程針對不同年度、部門、產品重複執行時,帶參數的 Macro 很有用。
%macro report_by_grade(target=A);
proc print data=work.classroom3;
where grade = "&target";
title "成績等級為 &target 的學生";
run;
%mend;
%report_by_grade(target=A);
%report_by_grade(target=B);
實務案例:依年份產出報表
%macro yearly_report(year=2025);
proc print data=work.sales_clean;
where year(order_date) = &year;
var order_id order_date customer_id revenue region;
title "年度銷售報表 - &year";
run;
%mend;
%yearly_report(year=2024);
%yearly_report(year=2025);
Macro 不是直接做資料分析,它更像是「程式碼產生器」與「流程自動化工具」。
初學者常混淆:Macro 變數 vs 一般資料欄位
- Macro 變數:在程式碼展開前使用,例如
&year。 - 資料欄位:存在於資料集裡,例如
order_date、revenue。 - 一句話記住:Macro 控制程式;DATA Step / PROC 處理資料。
六、SAS 範例應用案例
以下是你在作業、職場報表、資料分析中最常碰到的幾種情境。
案例 1:學生成績分級
任務:讀入學生分數,計算平均,並依分數給等級。
data work.student_scores;
input id name $ chinese english math;
average = mean(chinese, english, math);
if average >= 90 then grade = "A";
else if average >= 80 then grade = "B";
else if average >= 70 then grade = "C";
else grade = "D";
datalines;
1 Amy 92 88 95
2 Ben 70 76 80
3 Cara 85 90 87
;
run;
proc print data=work.student_scores;
run;
案例 2:銷售資料清理與統計
任務:建立營收欄位、修正常見缺值,再統計各地區營收。
data work.sales_clean;
set work.sales_raw;
revenue = qty * price;
if missing(region) then region = "UNKNOWN";
format revenue comma12.2;
run;
proc means data=work.sales_clean n sum mean maxdec=2;
class region;
var revenue;
run;
案例 3:會員與訂單資料 JOIN
任務:把訂單表與會員主檔合併,建立完整分析資料集。
proc sql;
create table work.order_full as
select a.order_id,
a.customer_id,
a.amount,
b.customer_name,
b.level
from work.orders as a
left join work.customers as b
on a.customer_id = b.customer_id;
quit;
案例 4:自動化產出每月報表
任務:寫成 Macro,減少每月重複改程式的時間。
%macro monthly_sales(month=1);
proc print data=work.sales_clean;
where month(order_date) = &month;
var order_id order_date region revenue;
title "月份報表 - &month 月";
run;
%mend;
%monthly_sales(month=1);
%monthly_sales(month=2);
綜合練習:從原始資料到最終報表
/* 1. 原始資料清理 */
data work.sales_clean;
set work.sales_raw;
revenue = qty * price;
if missing(region) then region = "UNKNOWN";
if qty <= 0 then delete;
format order_date yymmdd10. revenue comma12.2;
run;
/* 2. 排序 */
proc sort data=work.sales_clean out=work.sales_sorted;
by region descending revenue;
run;
/* 3. SQL 彙總 */
proc sql;
create table work.sales_summary as
select region,
count(*) as n_orders,
sum(revenue) as total_revenue format=comma12.2,
mean(revenue) as avg_revenue format=comma12.2
from work.sales_clean
group by region
order by total_revenue desc;
quit;
/* 4. 輸出結果 */
proc print data=work.sales_summary;
title "各地區銷售摘要";
run;
七、互動小測驗
做完以下題目,檢查你是否已掌握 SAS 的基礎觀念。
八、參考資料與延伸學習
以下為可延伸閱讀的官方文件與重點方向。若你之後要深入統計分析、圖表或 ODS 輸出,可以再往進階主題延伸。