99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀SAS程序錯(cuò)誤及處理
SAS程序錯(cuò)誤及處理
2017-03-30
收藏

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

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }