
SAS程序錯(cuò)誤及處理
通常我們所開發(fā)的SAS程序,很少在第一次提交時(shí)就能夠運(yùn)行完成并產(chǎn)生正確結(jié)果。程序越長越復(fù)雜,就越可能出現(xiàn)語法或邏輯錯(cuò)誤。本文介紹了一些良好的SAS編程規(guī)范以減少程序錯(cuò)誤,同時(shí)也描述了幾種常見的錯(cuò)誤及錯(cuò)誤發(fā)生后對應(yīng)的處理方法。
良好的SAS編程風(fēng)格
在開發(fā)SAS程序的過程中,遵循下面幾條規(guī)則可以使程序出錯(cuò)的幾率變小,并幫助發(fā)現(xiàn)錯(cuò)誤。
(1)提高程序的易讀性
一個(gè)簡單的方式是在開發(fā)程序時(shí)保持代碼的整潔和一致。易讀的程序會(huì)更易于調(diào)試,長期來看會(huì)節(jié)省時(shí)間。在編寫SAS程序時(shí)可遵循如下建議以提高程序的易讀性:
每行一條SAS語句。SAS允許在一行寫多個(gè)SAS語句,這樣會(huì)節(jié)省代碼空間,但是這些空間會(huì)以損失程序的易讀性為代價(jià)。
(2)測試程序每個(gè)部分
在開始寫下一部分的代碼之前,先測試前面已經(jīng)完成的代碼,保證已經(jīng)完成的代碼運(yùn)行正確會(huì)極大地提高開發(fā)效率。
如果是從外部數(shù)據(jù)文件讀取數(shù)據(jù)到SAS數(shù)據(jù)集,則使用PROC PRINT打印SAS數(shù)據(jù)集或數(shù)據(jù)集的部分?jǐn)?shù)據(jù),以保證該數(shù)據(jù)集被正確生成。有時(shí),在日志中可能沒有錯(cuò)誤或可疑的提示,而所生成的數(shù)據(jù)集卻是不正確的。這是因?yàn)樗_發(fā)的代碼可能并沒有如預(yù)期的讀取數(shù)據(jù),或原始數(shù)據(jù)本身存在某些在開發(fā)代碼時(shí)沒有意識(shí)到的問題。對此,好的習(xí)慣是,對程序創(chuàng)建的所有SAS數(shù)據(jù)集都至少要打印一次,以進(jìn)行檢查。
(3)正式運(yùn)行程序前使用較小的數(shù)據(jù)集測試程序
有時(shí),使用全部數(shù)據(jù)測試程序是不現(xiàn)實(shí)的。如果數(shù)據(jù)文件特別大,測試所有的數(shù)據(jù)會(huì)很費(fèi)時(shí),這時(shí)可以使用數(shù)據(jù)的子集來進(jìn)行測試。
如果是從文件中讀取數(shù)據(jù),可以在INFILE語句中使用OBS=告訴SAS讀取文件中的前多少行,例如前50、前100行或更多,只要能代表要讀取的數(shù)據(jù)就行。下面的代碼僅僅讀取文件的前100行:
還可以使用選項(xiàng)FIRSTOBS=指定從文件的中間部分開始讀取數(shù)據(jù)。例如,下面的語句讀取customer.dat文件的第101行到第200行:
同樣選項(xiàng)FIRSTOBS=和OBS=也可以用于在SET語句中讀取該數(shù)據(jù)集中對應(yīng)的觀測。下面的代碼會(huì)讀取數(shù)據(jù)集saslib.customer中的第101到第200個(gè)觀測。
關(guān)于SET語句及數(shù)據(jù)集選項(xiàng),下面文章會(huì)詳細(xì)介紹。
(4)使用語法敏感的編輯器
在Windows操作系統(tǒng)下,增強(qiáng)型編輯器(Enhanced Editor)是默認(rèn)的編輯器,在其他操作系統(tǒng)下,程序編輯器(Program Editor)是默認(rèn)編輯器。這兩種編輯器都會(huì)對代碼的不同部分自動(dòng)添加顏色,例如SAS關(guān)鍵字是一種顏色,變量是另一種顏色。此外,所有引號(hào)中的文本也是同樣的顏色,這樣我們可以很容易區(qū)分是否存在引號(hào)不匹配的情況。類似地,遺漏分號(hào)也很容易發(fā)現(xiàn),因?yàn)榉痔?hào)遺漏可能會(huì)導(dǎo)致接下來的代碼顏色不正確。
常見錯(cuò)誤及處理
SAS程序提交執(zhí)行后會(huì)在日志窗口或日志文件中產(chǎn)生代碼運(yùn)行的信息。我們可以根據(jù)日志信息確定什么時(shí)候程序發(fā)生錯(cuò)誤,并獲取信息糾正錯(cuò)誤。SAS通常會(huì)識(shí)別四類錯(cuò)誤:
SAS檢測到錯(cuò)誤時(shí),通常會(huì)將錯(cuò)誤或檢測到錯(cuò)誤的位置加下劃線,并顯示一個(gè)數(shù)字。每個(gè)數(shù)字與一條錯(cuò)誤消息唯一關(guān)聯(lián)。接著SAS進(jìn)入語法檢查模式,它會(huì)讀取剩下的程序語句、檢查語法,并在其他錯(cuò)誤位置加下劃線。
在批處理或非交互式的程序中,DATA步中的錯(cuò)誤會(huì)導(dǎo)致SAS對剩下的程序一直處于語法檢查模式,其他任何創(chuàng)建外部文件或SAS數(shù)據(jù)集的DATA或PROC步都不會(huì)執(zhí)行。然而,讀SAS數(shù)據(jù)集的過程會(huì)執(zhí)行,但是讀入的觀測數(shù)會(huì)為0,而不讀SAS數(shù)據(jù)集的過程正常執(zhí)行。通常PROC步中的語法錯(cuò)誤僅僅影響當(dāng)前PROC步。在該P(yáng)ROC步結(jié)束時(shí),SAS會(huì)將檢測到的每個(gè)錯(cuò)誤寫入SAS日志。
語法錯(cuò)誤
有些語法錯(cuò)誤從日志窗口中很容易理解并改正,有時(shí)SAS還會(huì)自動(dòng)糾正并提示警告信息,例如在圖2.50中展示的是關(guān)鍵字拼寫錯(cuò)誤。關(guān)鍵字INPUT錯(cuò)誤拼寫為INYUT,SAS給出警告信息并將該拼錯(cuò)的詞理解為INPUT。這樣,編譯會(huì)通過,代碼也會(huì)正確執(zhí)行。但SAS并不負(fù)責(zé)將代碼中的錯(cuò)誤改正,需要開發(fā)人員自己修正。
圖2.50 關(guān)鍵字拼寫錯(cuò)誤
很多語法錯(cuò)誤是由于遺漏分號(hào)(;)導(dǎo)致的,根據(jù)其在日志窗口的消息,可能沒那么容易找到出錯(cuò)原因。在下面的代碼中,DATA語句指定了數(shù)據(jù)集名稱之后遺漏分號(hào)(;)。
提交代碼執(zhí)行時(shí),因?yàn)檫z漏分號(hào),SAS認(rèn)為DATA語句中沒有結(jié)束,length和Name都被當(dāng)作數(shù)據(jù)集名。SAS無法解釋接下來出現(xiàn)的$,所以認(rèn)為出錯(cuò)。SAS在日志中顯示了如圖2.51所示的信息:在$出現(xiàn)的地方加劃線,并給出期待在這個(gè)地方出現(xiàn)的名稱或符號(hào),并提示出錯(cuò)。
圖2.51 遺漏分號(hào)
這時(shí)需要通過在DATA語句數(shù)據(jù)集名稱之后添加分號(hào)(;)來修正該段代碼。
數(shù)據(jù)錯(cuò)誤
在下面的程序中,INPUT語句使用列表方式讀取數(shù)據(jù)值。要讀取的最后一個(gè)變量為數(shù)字型變量,但輸入數(shù)據(jù)中第三行記錄的最后一個(gè)字段為字符。
提交執(zhí)行后查看日志窗口信息,如圖2.52所示。SAS提示在第10~13列(因?yàn)槭橇斜磔斎敕绞?,所以要賦值給Price的是“five”,對應(yīng)于第10~13列)的數(shù)據(jù)對變量Price無效。為了便于分析和修正,SAS還在日志窗口列出了輸入緩沖區(qū)的值、PDV中各變量的值,包括DATA步中定義的變量和自動(dòng)變量_ERROR_和_N_等。該數(shù)據(jù)錯(cuò)誤只是會(huì)導(dǎo)致所生成的觀測中存在缺失值,DATA步并不會(huì)停止執(zhí)行。
圖2.52 數(shù)據(jù)錯(cuò)誤
對于這樣的問題,有多種處理方式。在本例中可以不作處理,因?yàn)樗皇菚?huì)導(dǎo)致觀測中存在缺失值。其他類似的情況,可以通過調(diào)整輸入方式,例如使用格式化輸入等方法來解決。
語義錯(cuò)誤
在下面的程序中,DATA步讀取外部數(shù)據(jù)文件,并指定文件中字段值之間的分隔符為逗號(hào)(,)。注意,其中INFILE語句的選項(xiàng)DLM=誤寫為DLMA=了。
提交程序執(zhí)行后查看日志窗口的信息,如圖2.53所示。SAS提示選項(xiàng)名稱DLMA無效。因?yàn)槌鲥e(cuò),SAS停止處理并創(chuàng)建沒有觀測值的數(shù)據(jù)集。
圖2.53 語義錯(cuò)誤
這時(shí)需要更正該選項(xiàng)名稱為DLM=,并再次提交執(zhí)行。
引號(hào)不配對
在執(zhí)行SAS程序時(shí),有時(shí)會(huì)出現(xiàn)比較意外的情況。例如提交了代碼后,并不產(chǎn)生任何結(jié)果,日志窗口僅顯示代碼信息,沒有對應(yīng)的SAS語句執(zhí)行提示信息。不知道SAS在干什么,有時(shí)編輯器窗口會(huì)一直表示PROC步正在運(yùn)行。這時(shí)首先需要檢查是不是存在代碼中引號(hào)不配對的問題。
在下面的代碼中,F(xiàn)ILNAME語句指定文件引用時(shí),文件名結(jié)束后遺漏了對應(yīng)的單引號(hào)(")。
提交代碼執(zhí)行,并查看日志窗口,有原始代碼,但沒有語句執(zhí)行提示信息,如圖2.54所示。
圖2.54 SAS程序運(yùn)行不結(jié)束
遇到的這樣的問題,建議先提交下列代碼將引號(hào)配對,從而使程序完成執(zhí)行過程,再來檢查修正程序的錯(cuò)誤。這三行代碼除了可以解決不匹配的單引號(hào)和雙引號(hào)外,還可以解決不匹配的注釋標(biāo)記,以及遺漏分號(hào)、QUIT或RUN語句的問題:
結(jié)語
“讀取外部數(shù)據(jù)到SAS數(shù)據(jù)集”系列文章首先介紹了SAS編程的基本概念,具體包括SAS邏輯庫、SAS數(shù)據(jù)集、SAS數(shù)據(jù)集管理、系統(tǒng)選項(xiàng)以及SAS程序結(jié)構(gòu)等內(nèi)容;在此基礎(chǔ)上介紹了DATA步處理數(shù)據(jù)的原理,重點(diǎn)講解了如何使用DATA步的各種輸入方式來讀取不同格式的外部文件中的數(shù)據(jù),并創(chuàng)建數(shù)據(jù)集;接下來介紹了如何運(yùn)用IMPORT過程讀取外部的數(shù)據(jù)文件,以及如何通過LIBNAME語句和PROC SQL訪問關(guān)系型數(shù)據(jù)集庫系統(tǒng)中的數(shù)據(jù);最后,還介紹了SAS程序開發(fā)中常見的幾種錯(cuò)誤現(xiàn)象及其處理方法。
程序的不同部分使用相應(yīng)的縮進(jìn)。縮進(jìn)DATA步和PROC步中的所有語句,這種方式會(huì)很容易得知程序中有多少個(gè)DATA和PROC步,并且知道那些語句屬于哪個(gè)過程步。
代碼中引用的所有SAS文件都使用二級(jí)名稱,例如work.customer,即使該SAS文件存儲(chǔ)在WORK臨時(shí)邏輯庫或USER邏輯庫中。
使用RUN或QUIT語句顯式地表明DATA步或PROC步結(jié)束。雖然SAS會(huì)在遇到下一個(gè)DATA步或PROC步時(shí)自動(dòng)認(rèn)為當(dāng)前過程步結(jié)束,但是RUN或QUIT語句會(huì)讓程序塊邏輯更清楚。
使用注釋說明程度代碼段。給程序添加注釋可能會(huì)花一些額外的時(shí)間,但是很多時(shí)候注釋很重要,尤其是當(dāng)其他人查看或使用代碼時(shí)。
語法錯(cuò)誤。語法錯(cuò)誤是在SAS語句中犯的錯(cuò)誤,包括單詞誤拼寫、遺漏或無效的標(biāo)點(diǎn)符號(hào)、無效的語句或數(shù)據(jù)集選項(xiàng)等。
執(zhí)行時(shí)錯(cuò)誤。當(dāng)程序提交執(zhí)行時(shí),執(zhí)行時(shí)錯(cuò)誤會(huì)讓程序失敗。大多數(shù)不嚴(yán)重的執(zhí)行時(shí)錯(cuò)誤會(huì)在SAS日志中產(chǎn)生提示消息,但是程序能繼續(xù)運(yùn)行。但如果是更嚴(yán)重的錯(cuò)誤,SAS會(huì)打印錯(cuò)誤消息并停止處理。
數(shù)據(jù)錯(cuò)誤。數(shù)據(jù)錯(cuò)誤是一種執(zhí)行時(shí)錯(cuò)誤。當(dāng)SAS程序正在分析的原始數(shù)據(jù)包含無效值時(shí)就會(huì)發(fā)生數(shù)據(jù)錯(cuò)誤。例如,INPUT語句中指定了數(shù)字變量,而原始數(shù)據(jù)記錄中的數(shù)據(jù)值是字符。數(shù)據(jù)錯(cuò)誤不會(huì)引起程序停止,但是會(huì)在SAS日志中產(chǎn)生提示信息。
語義錯(cuò)誤。語義錯(cuò)誤是另一種執(zhí)行時(shí)錯(cuò)誤,當(dāng)SAS語句形式是正確的,但有些選項(xiàng)或語句等的使用方式無效時(shí)會(huì)發(fā)生。例如,函數(shù)中指定的參數(shù)個(gè)數(shù)錯(cuò)誤、在只有字符變量有效的地方使用數(shù)字變量名或使用了沒有賦值的邏輯庫引用名等。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動(dòng)態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時(shí),“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(shí)(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點(diǎn)數(shù)據(jù)時(shí)的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營問題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動(dòng)下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動(dòng)決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10