用SAS如何读取数据
你可能有各種形式的數(shù)據(jù),包括手寫在紙上、存放在電腦上、或是在數(shù)據(jù)庫(kù)管理系統(tǒng)里,不論如何,總有一種方法可以讓SAS來讀取。
SAS讀取的數(shù)據(jù)的方法主要有以下幾種類型:
? 直接輸入;
? 從原始數(shù)據(jù)文件中創(chuàng)建一個(gè)SAS數(shù)據(jù)集(creating SAS data sets from raw data files);
? 將其他軟件中的數(shù)據(jù)文件轉(zhuǎn)換成SAS數(shù)據(jù)集;
? 直接讀取其他軟件的數(shù)據(jù)集;
直接輸入
?View table窗口可以讓你以表格形式輸入數(shù)據(jù),可以定義變量、設(shè)置屬性,如name、length和 type(character or numeric).
? SAS 企業(yè)向?qū)K
? SAS/FSP 模塊,是Full Screen Product的簡(jiǎn)稱,可以設(shè)計(jì)定制的數(shù)據(jù)輸入窗口,也有檢測(cè)數(shù)據(jù)輸入錯(cuò)誤的功能(The SAS/FSP product is licensed separately from Base SAS software.)。
從原始數(shù)據(jù)文件中創(chuàng)建一個(gè)SAS數(shù)據(jù)集
你有兩種方法讀取原始數(shù)據(jù)文件:
? 數(shù)據(jù)步可以讀取任何形式的原始數(shù)據(jù)文件,比如text, ASCII, sequential, flat files。
? 導(dǎo)入向?qū)?#xff08;Import Wizard)、導(dǎo)入過程(IMPORT procedure)適用于UNIX、OpenVMS和 Windows操作環(huán)境的簡(jiǎn)單方法,可以讀取CSV(comma-separated values)和其他一些限定的文件類型。
將其他軟件中的數(shù)據(jù)文件轉(zhuǎn)換成SAS數(shù)據(jù)集
如果數(shù)據(jù)在一個(gè)軟件中以某種格式存放,但需要用另一種軟件分析時(shí),就會(huì)很麻煩。有幾種方法可以將某種軟件中的數(shù)據(jù)轉(zhuǎn)換成SAS數(shù)據(jù)集:
? 如果安裝SAS/ACCESS模塊,可以用導(dǎo)入過程(import procedure)和導(dǎo)入向?qū)?#xff08;Import Wizard)將Excel、Lotus、dBase和Access文件導(dǎo)入SAS數(shù)據(jù)集。
? 如果沒有安裝,可以用存放數(shù)據(jù)的軟件創(chuàng)建一個(gè)原始文件,并用數(shù)據(jù)步或?qū)脒^程(import procedure)讀取。很多軟件都可以創(chuàng)建CSV文件。
? Windows操作環(huán)境下也可以用動(dòng)態(tài)數(shù)據(jù)交換技術(shù)(Dynamic Data Exchange,DDE)。前提是必須有一個(gè)其他的Windows程序與SAS同時(shí)運(yùn)行,再使用DDE和數(shù)據(jù)步。
直接讀取其他軟件的數(shù)據(jù)集
? SAS/ACCESS產(chǎn)品可以不用轉(zhuǎn)換數(shù)據(jù)格式讀取數(shù)據(jù),并適用于大部分?jǐn)?shù)據(jù)庫(kù)管理系統(tǒng),包括ORACLE,DB2,INGRES和 SYBASE(但使用方法本書沒有介紹)。
? 使用Excel engine和Access engine來讀取這兩種類型的數(shù)據(jù)。(SAS幫助文檔)
? 還有其他的一些數(shù)據(jù)引擎(data engines)來讀取數(shù)據(jù),如SPSS engine(附錄D),查
使用DATA步,通過INFILE語(yǔ)句指定原始數(shù)據(jù)文件;
SAS提供了以下3種基本輸入方式:
列表輸入
按列輸入
格式化輸入
一、列表輸入
1) FILENAME語(yǔ)句指定到單個(gè)文件的文件引用
2) FILENAME語(yǔ)句指定到一組外部文件存儲(chǔ)位置的文件引用
列表輸入(List Input)用于讀取原始數(shù)據(jù)記錄中每個(gè)字段由至少一個(gè)分隔符隔開,并且數(shù)據(jù)值中不包含該分隔符的原始數(shù)據(jù)。列表輸入默認(rèn)分隔符為空格,連續(xù)的分隔符會(huì)當(dāng)成一個(gè)分隔符處理,INPUT語(yǔ)句中包含了簡(jiǎn)單的變量名稱列表。
在SAS窗口中提交如下代碼:
INPUT語(yǔ)句會(huì)逐行順序地讀取inventory.dat中的數(shù)據(jù)值,并賦值給變量。在讀取每行數(shù)據(jù)時(shí),遇到空格就停止讀入當(dāng)前數(shù)據(jù)值,并從非空格處讀入下一個(gè)數(shù)據(jù)值。
3) 使用INFILE語(yǔ)句的選項(xiàng)DLM=指定分隔符
當(dāng)原始數(shù)據(jù)中數(shù)據(jù)記錄的數(shù)據(jù)值未使用空格,而是使用其他分隔符時(shí),需在INFILE語(yǔ)句中使用DLM=選項(xiàng),告訴SAS讀入數(shù)據(jù)時(shí)需要使用的分隔符。
下面將上面外部數(shù)據(jù)文件的內(nèi)容稍作修改以便比較。文件inventory_dlm.dat的內(nèi)容如下,數(shù)據(jù)記錄中的各數(shù)據(jù)值之間由逗號(hào)(,)隔開。
正確讀取該數(shù)據(jù)文件的代碼如下:
使用DLM=選項(xiàng)可處理原始數(shù)據(jù)記錄中數(shù)據(jù)值中包含空格的情況。此外,使用DLM=選項(xiàng)的DATA步也可以很好地處理數(shù)據(jù)中的缺失值。如果接連有多個(gè)指定的分隔符,也會(huì)當(dāng)成一個(gè)分隔符處理。但如果分隔符之間有空格,則該空格會(huì)當(dāng)作缺失值讀入變量并寫入數(shù)據(jù)集。例如,當(dāng)數(shù)據(jù)文件inventory_missing.dat的內(nèi)容如下:
注意:當(dāng)用dlm=“,”時(shí),想要識(shí)別缺失數(shù)據(jù)必須使用空格作為占位符,否則沒有空格只有兩個(gè)逗號(hào)時(shí),數(shù)據(jù)只會(huì)讀入該行的第一個(gè)數(shù)據(jù),并且之后的數(shù)據(jù)也不會(huì)讀入;
提交與上例相同的SAS代碼,PRINT過程打印的數(shù)據(jù)集內(nèi)容如下圖所示,其中第3個(gè)觀測(cè)Instock變量為默認(rèn)值:
4) 使用INFILE語(yǔ)句的選項(xiàng)DSD
DSD (Delimiter-Sensitive Data)
指定選項(xiàng)DSD后,如果數(shù)據(jù)值是由引號(hào)引起來的,可以將數(shù)據(jù)值中的分隔符當(dāng)成是數(shù)據(jù)值的一部分讀入,字符值中的引號(hào)在讀入PDV時(shí)會(huì)被刪除。DSD選項(xiàng)將默認(rèn)的分隔符設(shè)置為逗號(hào),還改變了使用列表輸入時(shí)SAS處理分隔符的方式,比如,如果有兩個(gè)連續(xù)的逗號(hào),將被當(dāng)作缺失值。
選項(xiàng)DSD還可以和其他選項(xiàng)(例如DLM=和DLMSTR=)一起使用。
5) 使用INFILE語(yǔ)句的選項(xiàng)missover
MISSOVER:會(huì)在DATA步的本次迭代中阻止INPUT語(yǔ)句讀入原始數(shù)據(jù)的下一條記錄,并將PDV中所有未賦值的變量保持為缺失值(PDV中變量未賦值時(shí)就為缺失值)。當(dāng)原始數(shù)據(jù)記錄中的最后一個(gè)或多個(gè)字段沒有值且沒有占位符時(shí),并且希望SAS將對(duì)應(yīng)的變量置為缺失值時(shí)使用MISSOVER。
外部數(shù)據(jù)文件missover.dat的內(nèi)容如下,依次包括課程編號(hào)、課程名稱、參加課程人數(shù)和講師姓名等信息。其中第二條記錄中未提供參加課程人數(shù)和講師姓名,也沒有占位符。
在INFILE語(yǔ)句中加上MISSOVER選項(xiàng),代碼如下:
PRINT過程打印的數(shù)據(jù)集如下圖所示:
5) 使用INFILE語(yǔ)句的選項(xiàng)turnover
默認(rèn)情況下(選項(xiàng)為FLOWOVER),當(dāng)原始數(shù)據(jù)記錄長(zhǎng)度小于INPUT語(yǔ)句的預(yù)期時(shí),INPUT語(yǔ)句自動(dòng)讀入下一條數(shù)據(jù)記錄。當(dāng)指定選項(xiàng)TRUNCOVER時(shí),即使當(dāng)前輸入行數(shù)據(jù)的長(zhǎng)度小于INPUT語(yǔ)句的預(yù)期,也會(huì)將當(dāng)前輸入行的數(shù)據(jù)賦值給當(dāng)前處理的變量,并將其他沒有賦值的變量設(shè)置為缺失值。
TRUNCOVER選項(xiàng)常用于處理變長(zhǎng)的原始數(shù)據(jù)記錄,可在INPUT語(yǔ)句中定義足夠長(zhǎng)度的變量,即使當(dāng)前數(shù)據(jù)記錄中的數(shù)據(jù)長(zhǎng)度小于變量指定的長(zhǎng)度,也可以將該記錄從緩沖區(qū)讀入PDV,并寫入數(shù)據(jù)集,以便進(jìn)一步處理。
原始數(shù)據(jù)文件comments.dat的內(nèi)容如下,共3條記錄,全部為文本,文本長(zhǎng)度不確定。
使用TRUNCOVER選項(xiàng)讀入該文件記錄。設(shè)置變量Text的輸入格式為“$500.”,當(dāng)原始記錄中文本長(zhǎng)度不足500個(gè)字符時(shí),TRUNCOVER選項(xiàng)會(huì)將當(dāng)前輸入緩沖區(qū)中的所有內(nèi)容寫入PDV,并寫入數(shù)據(jù)集。
PRINT語(yǔ)句打印的數(shù)據(jù)集內(nèi)容如下圖所示。可以看到,所有的評(píng)論信息都讀入了數(shù)據(jù)集中。
MISSOVER與TRUNCOVER的不同之處在于,如果當(dāng)前變量沒有讀到要求長(zhǎng)度的數(shù)據(jù),MISSOVER會(huì)將當(dāng)前變量的值也置為缺失值。還是以上面的示例為例,如果將TRUNCOVER換成MISSOVER,所生成的數(shù)據(jù)集中3個(gè)觀測(cè)值都為缺失值。
5) 使用INFILE語(yǔ)句的選項(xiàng)PAD
選項(xiàng)LRECL為系統(tǒng)選項(xiàng)指定用于讀寫外部文件的默認(rèn)邏輯記錄長(zhǎng)度。LRECL指定邏輯記錄的長(zhǎng)度為1(字節(jié))或1024(k字節(jié))的倍數(shù)。例如32表示32字節(jié)、16k表示16384字節(jié)。該選項(xiàng)的范圍為1~32767。在SAS 9.4中,LRECL系統(tǒng)選項(xiàng)默認(rèn)值為32767,通常不需要修改。
PAD和NOPAD選項(xiàng)控制SAS是否使用空格對(duì)從外部文件讀入的記錄進(jìn)行填充,使其達(dá)到選項(xiàng)LRECL=指定的長(zhǎng)度。默認(rèn)設(shè)置為NOPAD。
當(dāng)使用PAD選項(xiàng)時(shí),SAS會(huì)自動(dòng)用空格填充從外部文件中讀入的記錄長(zhǎng)度。
還是以上面的comments.dat文件為例:
下面在INFILE語(yǔ)句中使用PAD選項(xiàng),代碼如下:
PRINT過程打印的數(shù)據(jù)集內(nèi)容如下圖所示。DATA步正確讀入了文件中的所有評(píng)論。
6) 使用INFILE語(yǔ)句的選項(xiàng)控制輸入
FIRSTOBS=
FIRSTOBS= 選項(xiàng)告訴SAS從哪一行開始讀取數(shù)據(jù),當(dāng)數(shù)據(jù)開頭有些說明信息,或者想要跳過某些行時(shí),這個(gè)選項(xiàng)很有用。例如,如下原始數(shù)據(jù)文件中,開頭兩行是關(guān)于數(shù)據(jù)的描述:
那么用如下程序可以讓SAS從第三行開始讀取數(shù)據(jù):
OBS= OBS=告訴SAS一直讀取到哪一行位置,注意是行而不是觀測(cè)值(有的觀測(cè)值占據(jù)多行)比如,如下的原始數(shù)據(jù)文件中,結(jié)尾處還有一句不需要的數(shù)據(jù)說明時(shí)。就需要這個(gè)選項(xiàng):
用FIRSTOBS=3和OBS=5就可以讀取第三行到第五行的數(shù)據(jù):
二、按列輸入
當(dāng)原始數(shù)據(jù)記錄中的數(shù)據(jù)值在每條記錄中占據(jù)相同的列時(shí),可使用按列輸入的方式。按列輸入(Column Input)可以讀取固定列的數(shù)據(jù)。
文件customer.dat的內(nèi)容如下,其中,第114列為產(chǎn)品編號(hào),第1626列為附屬品牌,第2829列為專賣店數(shù),第3135列為產(chǎn)品庫(kù)存
數(shù)。
三、格式化輸入
上面介紹的按列輸入與列表輸入一樣,只能讀取標(biāo)準(zhǔn)的字符或數(shù)字值到數(shù)據(jù)集中。SAS還可以讀取特殊格式的數(shù)字?jǐn)?shù)據(jù),例如二進(jìn)制數(shù)據(jù)、日期/時(shí)間(01FEB2013),或者包含逗號(hào)(1,262)、貨幣符號(hào)($87.3)等特殊字符的數(shù)字值。在這種情況下,就需要使用格式化輸入(formatted input)了,即在INPUT語(yǔ)句中提供特殊的指令,以便SAS正確地讀取原始數(shù)據(jù)記錄中的數(shù)據(jù)值。這些特殊指令稱為輸入格式(Informat)。格式化輸入組合了按列輸入特征和讀取非標(biāo)準(zhǔn)化數(shù)字或字符值的能力,保證數(shù)據(jù)值可正確地從原始數(shù)據(jù)記錄中讀入。
來看個(gè)示例,原始數(shù)據(jù)文件sales.dat的內(nèi)容如下,該文件中原始數(shù)據(jù)記錄包含字段依次為員工ID、部門、銷售額和上次修改日期,其中銷售額和日期都不是標(biāo)準(zhǔn)數(shù)字值,需使用對(duì)應(yīng)的輸入格式。
讀入處理該文件的SAS代碼如下,其中Sales和Date變量分別使用了輸入格式comma6.和date9.,Emp_ID和Dept使用的是上面介紹過的按列輸入方式。
在INPUT語(yǔ)句中,還使用了相對(duì)列控制符號(hào)+1和絕對(duì)列控制符號(hào)@22,分別表示將當(dāng)前的輸入列控制指針向前移1位和將該指針直接移動(dòng)到列22。在上面的示例中,程序讀入一行記錄到輸入緩沖區(qū)后,列控制指針的移動(dòng)情況如下:
·第1~5列寫入Emp_ID,列控制指針在第6列。
·第7~9列寫入Dept,這時(shí)列控制指針在第10列。
·+1將列控制指針移到第11列。
·開始讀入comma6.中指定的6列,即將第11~16列使用輸入格式轉(zhuǎn)換后寫入Sales,這時(shí)列控制指針在第17列。
·@22將控制指針直接移到第22列,讀入date9.中指定的9列,即第22~30列,然后使用該輸入格式進(jìn)行轉(zhuǎn)換,并寫入Date。
四、帶修飾的列表輸入
將列表輸入、輸入格式和修飾符結(jié)合起來,結(jié)合后就成了帶修飾的列表輸入(modified list input),這樣可以使用列表輸入方式更靈活地讀入數(shù)據(jù)。
·&修飾符(ampersand format modifier):使用列表輸入時(shí),該修改符能夠讀入數(shù)據(jù)值中包含一個(gè)或多個(gè)嵌入空格的字符值,并指定字符的輸入格式。SAS讀入數(shù)據(jù)直到遇到兩個(gè)連續(xù)的空格或達(dá)到所定義的數(shù)據(jù)長(zhǎng)度或輸入行結(jié)束才停止。&修飾符解決了使用列表輸入方式讀取數(shù)據(jù)值中包含嵌入空格的問題,但要求該包含空格的數(shù)據(jù)值與下一個(gè)數(shù)據(jù)值之間至少間隔兩個(gè)空格。
·:修飾符(colon format modifier):使用列表輸入時(shí),該修改符可以在變量名后指定輸入格式。SAS讀入數(shù)據(jù)直到遇到空列、達(dá)到所定義的數(shù)據(jù)長(zhǎng)度(對(duì)字符型變量來說)或輸入行結(jié)束才停止。:修飾符可以讀取超過8個(gè)字節(jié)的字符數(shù)據(jù)和包含特殊字符的數(shù)字字符。
·~修飾符(tilde forat modifier):可以讀入并保持?jǐn)?shù)據(jù)值中的單引號(hào)、雙引號(hào)和分隔符。
原始數(shù)據(jù)文件customer2.dat的內(nèi)容如下,每條記錄包含聯(lián)系人信息:客戶ID、名字和出生日期,其中名字里面嵌入了空格,可使用&修飾符讀入。注意,使用&修飾符要求名字和出生日期之間為兩個(gè)空格。
處理該數(shù)據(jù)的SAS代碼如下,其中,Name變量使用了&修飾符讀入帶空格的名字,并指定輸入格式為$20.,所以Name變量的字符長(zhǎng)度為20個(gè)字節(jié),而且SAS會(huì)將緩沖區(qū)中的20個(gè)字符讀入Name。Birth_Date使用了:修飾符讀入日期格式的數(shù)據(jù)。
@’character’ 列指示器
@column列指示器可以讓SAS直接從某列開始讀取數(shù)據(jù)。但有時(shí)候你不知道要讀取的數(shù)據(jù)是從哪列開始,此時(shí)你只要知道要讀取的數(shù)據(jù)的前面那個(gè)字符或單詞即可。比如有一個(gè)關(guān)于狗的原始文件,你想要讀取狗的品種號(hào),但文件排列很凌亂,只知道品種號(hào)跟隨在單詞breed后面,那么可以用如下方式讀取:
Input @’Breed:’ DogBreed $;
例子 web日志是凌亂數(shù)據(jù)的一個(gè)很好例子,下面是一個(gè)網(wǎng)站的web日志,數(shù)據(jù)開始于訪問IP,后面有訪問日期、訪問文件名等信息。
現(xiàn)在想要讀取訪問日期和訪問的文件名,但是它們每行中所占據(jù)的列的位置都不同,而且文件名的長(zhǎng)度每行都不一樣,那么SAS讀取這種文件通過如下方式:
@’[’作為列指示器,告訴SAS讀取[之后的內(nèi)容,@’GET’告訴SAS讀取GET之后的內(nèi)容,由于文件名作為字符串變量,這里基本都會(huì)超過8個(gè)字節(jié),因此后面附加:$20。輸出結(jié)果如下:
五、混合輸入
在使用INPUT語(yǔ)句時(shí)不限于使用一種輸入方式,可以在一條INPUT語(yǔ)句中混合使用這些輸入方式,只要可以適當(dāng)?shù)孛枋鲈紨?shù)據(jù)記錄就行。
原始數(shù)據(jù)文件mixedinput.dat的內(nèi)容如下,其中依次包括了課程編號(hào)、課程名稱、開課日期和報(bào)名人數(shù)等信息。
列表輸入讀取Course_ID和Attendee、按列輸入讀取Course_Name、格式化輸入讀取Open_Date。代碼如下:
跨行觀測(cè)值的讀取方式:
一般原始文件中一行代表一個(gè)觀測(cè)值,有時(shí)會(huì)出現(xiàn)一個(gè)觀測(cè)值跨行的情況。由于SAS會(huì)自動(dòng)轉(zhuǎn)到下一行讀取數(shù)據(jù),直到讀取這個(gè)觀測(cè)的所有變量(input語(yǔ)句中給出),所以你需要告訴SAS什么時(shí)候不要換行,以便在日志中不出現(xiàn)SAS-went-to-a-new-line的暫停說明,此時(shí)需要在INPUT語(yǔ)句中加行指示器。
行指示器,斜線/:告訴SAS跳至原始數(shù)據(jù)的第二行;#n:跳至第n行,n代表原始數(shù)據(jù)中某觀測(cè)值的行數(shù)(#2則讓SAS跳至某觀測(cè)值的第二行),#n不能用來回跳。
例子 有一組關(guān)于溫度的數(shù)據(jù),temperature.dat第一行代表城市和州,第二行代表本日最高溫和最低溫,第三行代表史上最高溫和最低溫。
用如下的程度來讀取這份數(shù)據(jù):
Input后面告訴SAS讀取第一行的city變量和state變量,斜線/告訴SAS移動(dòng)到下一行的第一列,以便讀取normalhigh和normallow。#3告訴SAS移動(dòng)到第三行的第一列以便繼續(xù)讀取觀測(cè)值的recordhigh變量和recordlow變量。這里/可以用#2代替,也可以用/代替#3。
日志記錄如下:
輸出結(jié)果如下:
一行有多個(gè)觀測(cè)值的原始文件讀取
當(dāng)一行出現(xiàn)多個(gè)觀測(cè)值時(shí),可以在input語(yǔ)句結(jié)尾加一個(gè)停止符號(hào)@@
例子 有一個(gè)關(guān)于降水量的數(shù)據(jù),precipitation.dat,文件包含城市名、州名、月平均降水量、月平均降水天數(shù):
這個(gè)數(shù)據(jù)文件中,第一行包含了兩個(gè)觀測(cè)值,可以用@@的程序讀取:
輸出結(jié)果如下:
讀取原始數(shù)據(jù)的部分觀測(cè)值
有時(shí)候只需要讀取原始數(shù)據(jù)的部分觀測(cè)值,比如只需要年鑒中的女性數(shù)據(jù)、收入超過10萬的人口數(shù)據(jù)等。此時(shí)的數(shù)據(jù)讀取方式如下:在SAS讀取某一行觀測(cè)值時(shí),首先讀取足夠的變量以便決定是否需要保留此行的觀測(cè)值。然后在input語(yǔ)句結(jié)尾加符號(hào)@,叫做a trailing at(called a trailing at),這告訴SAS先停在(hold)此行,同時(shí)用IF語(yǔ)句檢測(cè)此觀測(cè)值是否滿足需要,如果是,那么可以再用一個(gè)input語(yǔ)句來讀取現(xiàn)有的變量。
例子 有一個(gè)關(guān)于當(dāng)?shù)亟煌ǖ臄?shù)據(jù),traffic.dat數(shù)據(jù)包含街道的類型(freeways和surface)、街道名稱、早晨每小時(shí)的機(jī)動(dòng)車流動(dòng)量、晚上每小時(shí)機(jī)動(dòng)車流動(dòng)量。
如果現(xiàn)在你只需要freeway的數(shù)據(jù),可以用下述程序:
第一個(gè)input讀取字符串變量,@是SAS停留在觀測(cè)值上并用IF檢測(cè),第二個(gè)input讀取input后面的變量值。
輸入結(jié)果如下所示:
@ vs @@ ,@的作用類似于@@,都是行停留指示符(line-hold specifiers),不同地方在于停留多久,@能使SAS停留到下一個(gè)input語(yǔ)句(也不換行),@@能使停留的時(shí)間到下一個(gè)data步(也不換行)。
比如這段代碼:
data test;
infile cards ;
input x @;
input y;
input z @@;
cards;
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17
;
run;
test輸出結(jié)果就是:
****************************************************** The End ***************************************************
總結(jié)
以上是生活随笔為你收集整理的用SAS如何读取数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 审计一家言读后感
- 下一篇: B站首个千万级up主!论老番茄是如何炼成