第二章 建立SAS數據集
前面我們介紹了關於SAS系統的一些基本概念以及基本的操作過程。我們知道SAS是以數據爲中心的一個應用軟件系統,一般來說,一個SAS的程序的運行,離不開SAS的數據集,數據必須以SAS數據集的格式存放才能被許多SAS程序處理。本章我們介紹建立SAS數據集的兩種基本方法。
一.利用窗口輸入數據
首先我們介紹一種比較直觀,也比較簡單的方法來建立SAS數據集,就是利用SAS/FSP模塊中的過程FSEDIT 和FSVIEW來進行。
1. The FSEDIT and FSVIEW Procedures(FSEDIT 和FSVIEW過程)
SAS/FSP模塊對SAS數據的輸入、編輯等提供了非常方便的用戶截面,它由以下一些過程組成:
過程名 |
用途 |
FSBROWSE |
顯示SAS數據文件的內容 |
FSEDIT |
顯示、輸入、修改SAS數據文件的內容 建立新的SAS數據集 |
FSLETTER |
建立、編輯、打印格式化的信件和報告 |
FSLIST |
瀏覽外部(非SAS)文件 |
FSVIEW |
以表格方式顯示、輸入、修改SAS數據文件的內容 建立新的SAS數據集 |
我們將介紹其中可用於建立SAS數據集的FSEDIT 和FSVIEW過程。
1) 如果使用FSEDIT過程輸入或修改SAS數據集的內容,它每次顯示一個觀測(observation)中的內容。
2) 如果使用FSVIEW過程輸入或修改SAS數據集的內容,你可以同時看到多個觀測(observations)中的內容。
例:用FSEDIT 和FSVIEW過程修改SAS數據集時分別會顯示
FSEDIT |
Obs 1 |
|
FSVIEW |
|
|
|
|
|
|
OBS |
NAME |
DEPT |
ROOM |
NAME |
Joe Wise |
|
1 |
Joe Wise |
Sales |
G-320 |
DEPT |
Sales |
|
2 |
Sam Chow |
Mkt |
F-110 |
ROOM |
G-320 |
|
3 |
Sue Hart |
CBT |
A-309 |
INDATE |
03/24/79 |
|
4 |
Jan Grime |
QC |
X-180 |
使用FSEDIT 或FSVIEW過程建立SAS數據集的步驟:
1) 提交一個過程步,指明要創建的數據集,FSEDIT 或FSVIEW過程的運行會打開FSEDIT NEW或FSVIEW NEW窗口
2) 在FSEDIT NEW或FSVIEWNEW窗口指定變量的特徵信息
3) 關閉FSEDIT NEW或FSVIEWNEW窗口,進入FSEDIT 或FSVIEW窗口,創建觀測並輸入數據。注意:一旦離開NEW窗口,就無法再回去了。
4) 結束該過程,並保存數據集。
2. Creating a New Data Set(建立新的數據集)
現在,我們假設你要建立一個永久的數據集,也就是說,你要建立的數據集將防在一個永久的SAS數據庫中。因此,在建立你的數據集之前,先要用LIBNAME語句給你的數據庫指定一個標記(libref),用法:
LIBNAME libref 'SAS-data-library';
然後,調用FSEDIT 或FSVIEW過程創建新的數據集,用法:
PROCFSEDIT NEW=sas-date-set;
或 PROC FSVIEW NEW=sas-date-set;
例:在程序編輯器中輸入以下程序:
libname students 'd:\hu\data1';
proc fsedit new=students.f97;
run;
然後,選擇 LocalsàSubmit 提交這段程序,就會出現FSEDIT NEW窗口。在這個窗口中,你就可以設定數據集students.f97中有多少變量及各變量的屬性。
3. Specifying Variable Attributes(設定變量的屬性)
在FSEDIT NEW或FSVIEW NEW窗口中,每一行代表一個變量,每一列表示變量的一種屬性,你可以在表中填寫來設定新數據集中的變量。這些屬性包括:
1)變量名(Name):要創建的變量的名字,要符合SAS的命名規則。
2)類型(Type):變量的類型,字符用$或C表示,數字用N或空格表示,缺省爲數字。
3)長度(Length):變量的長度,字符型變量不超過200,缺省爲8字節。注意,對數字型變量,長度爲2-8,是指儲存該變量的字節數,而非數字(或小數點)位數。
4)標記(Label):用於說明該變量,長度爲1-40的字符串。
5)格式(Format):變量的輸出格式。
6)輸入格式(Informat):變量的輸入格式。
其中,屬性1)2)3)是每一個變量所必須有的。
注意:窗口中只出現Format和Informat其中之一,可選擇用 LocalsàFormat/Informat進行來回切換。
完成數據集中所有變量的設定以後,仔細檢查一遍,然後選擇
Viewà End
退出NEW窗口,你便會進入FSEDIT或FSVIEW的窗口,輸入你的觀測數據。
4. Creating a Data Set Like an ExistingOne(創建有同樣結構的數據集)
如果你要創建的新數據集與某一已有的數據集有相同或相近的結構的話,就是說兩者中的變量數及其屬性都一樣或只有很少不同的話,你可以利用FSEDIT或FSVIEW過程的LIKE選項來提高創建新數據集的效率。
例如:在程序編輯器中輸入以下程序:
proc fsview new=students.f97 like=students.f96;
run;
然後,提交這段程序,就會出現FSVIEWNEW窗口。在這個窗口中,對數據集students.f97已預先設定好與students.f96完全相同的變量結構,你可在此基礎上進行修改,或全盤接受,然後退出FSVIEWNEW窗口,進入FSVIEW的窗口,輸入觀測數據。
5. Editing Commands(編輯命令)
你可以分別用以下的操作命令來輸入或修改你創建的數據集中的數據
1)在FSEDIT中
操作命令 |
功能 |
Edit à Add new record |
創建並顯示一個新的空的觀測 |
Edit à Delete record |
刪除當前顯示的觀測 |
Edit à Duplicate record |
複製當前顯示的觀測,並顯示該新觀測供編輯 |
在窗口上方會顯示是第幾個觀測,用“PageUp”和“Page Down”鍵可在已有的觀測之間移動。
2)在FSVIEW中
操作命令 |
功能 |
Edit à Autoadd |
自動在最後創建並顯示一個新的空的觀測 |
Edit à Delete … |
刪除當前顯示中的某一個或幾個觀測 |
Edit à Duplicate … |
複製當前顯示中的某一個或幾個觀測 |
可用“Tab”鍵是光標在不同的變量之間移動,輸入或修改完最後一個觀測中的變量後,按“Enter”可進入自動在最後創建的新觀測。
二.利用數據步讀取數據
1. Introductionto DATA Step(數據步簡介)
SAS的數據步由一組SAS語句組成,它由DATA語句作爲開始。在執行過程中,DATA語句使系統開始建立一個數據集,並指明該數據集的名字。系統會檢查數據步的語法,如果語法正確,數據步中的語句就會被執行,數據集就會建立起來。
1)數據步的一般語法
利用數據步建立SAS數據集,有兩種方式可以輸入數據:一是將數據數據排列在變量名串之後;二是數據的出處,也就是指定一個外部數據文件供讀取。
第一種方式的一般語法爲:
DATAsas-data-set-name;
INPUT var1var2;
CARDS;
d11 d12
d21 d22
d31 d32
d41 d42
;
RUN;
例:
DATAstudent.f96;
INPUT numbername $;
CARDS;
9641001 zhao
9641002 qian
9641003 shun
9641004 li
;
RUN;
其中,DATA、INPUT和CARDS三個關鍵詞缺一不可,注意數據集名和變量名要符合SAS命名規則。
第二種方式的一般語法爲:
DATAsas-data-set-name;
INFILE 'input-file-name';
INPUTvar1 var2;
RUN;
例:
DATAstudent.f96;
INFILE'd:\student\f96.txt';
INPUT numbername $;
RUN;
第二種方式中用INFILE語句指定了一個外部數據文件,所有需要輸入的數據存放在該文件中,從而取代了第一種方式中的CARD語句及其下列的一連串數據,當數據比較多的時候,用第二種方式可以使程序看上去顯得比較簡潔。注意,這裏,INFILE語句在INPUT語句之前,而在第一種方式中,CARD語句在INPUT語句之後。下面,我們主要以第二種方式爲例來進行介紹。
2)指定數據集的名字
DATA語句指定了我們要建立的SAS數據集的名字。一個SAS數據集也是一個SAS文件,SAS系統通過一個二級名來識別一個SAS文件,二級名的組成爲: libref.filename。其中,libref爲庫標記,filename爲文件名,當libref=work時,庫標記可省略。
3)指定外部數據文件
INFILE語句用於指定一個包含原始數據的外部文件,它必須在INPUT語句之前執行。該語句的一般形式爲:
INFILE'file-name' options;
file-name即爲該外部文件名,包含其路徑,兩邊用單引號。如果該文件名包括其路徑比較長,或在程序中會不止一次用到的話,可在程序開始用FILENAME語句給它設定一個文件標記(fileref),文件標記的性質可類比與數據庫標記(libref)。
利用INFILE語句中的選項(options)可以有選擇地讀取外部文件中的記錄:
A. FIRSTOBS=n1表示從第n1條記錄開始讀取
B.OBS=n2表示共讀取n2條記錄
4)指定變量名及其屬性
INPUT語句要指定如何讀取數據並將之賦予每個變量。因此,在INPUT語句中,你必須給出:
A. 有效的SAS變量名
B. 變量的類型和長度
INPUT語句的一般形式爲(採用列模式時):
INPUT variable $ startcol-endcol;
5)檢查數據集內容
當你成功地建立了一個數據集以後,你可能很想看一下這個數據集中的內容,檢查一下是否有差錯。你可以用FSVIEW過程或PRINT過程來顯示所生成的數據集。用法分別爲:
PROCFSVIEW DATA=sas-data-set-name; run;
或 PROC PRINT DATA==sas-data-set-name;run;
FSVIEW過程在FSVIEW窗口中顯示數據集內容;而PRINT過程在OUTPUT窗口中顯示數據集內容。
6)例子
下面我們看一個數據步的例子:
libname student 'd:\users\hu\sas\tudents'; 指定數據庫標記
filename f97data 'd:\users\hu\data\student\f97.dat' 指定外部數據文件標記
data student.f97; 指定創建的數據集名
infile f97data; 指定用於讀取數據的外部文件
input number 1-7name $ 9-16 score 18-20 指定數據集變量及屬性
proc print data=student; 檢查數據集內容
run; 使以上程序步運行
2. ReadingData in Fixed Fields(按固定列讀取數據)
1)固定域數據
在文件中,原始數據可以按照列,或者固定的域來組織,比如:
----+----1----+----2----+
BIRDFEEDER |LG088| 3|20
6 GLASS MUGS|SB082| 6|12
GLASSTRAY |BQ049|12| 6
PADDEDHANGRS|MN256|15|20
JEWELRYBOX |AJ498|23| 0
REDAPRON |AQ072| 9|12
對於這種按固定域排列的原始數據,SAS提供兩種數據讀入方式:列模式和格式化模式。
列模式輸入及其優點
按列模式輸入,對每一個域都設定其開始和結束的列,字符變量用$號表示。比如,對上面的數據,INPUT語句的寫法爲:
inputitem $ 1-13 idnum 15-19 instock 21-22 backord 24-25;
採用列模式輸入有不少好處:
A. 可以按任意順序讀取這些域
B. 字符型變量可以長達200字符,並且內含空格
C. 空域被認爲是遺漏數據,不會引起誤讀其它域的問題
D. 域或域的部分可以被重讀
E. 域之間不需要用空格或其它符號分隔
標準與非標準數據
標準的數字型變量數據僅包含數字、科學記數符號、小數點和負號。字符型變量數據可包含任意字符、下劃線、數字和符號。如果數字型變量數據中包含諸如逗號和美元符號的話,就被認爲是非標準數據,非標準數字型變量包括:
A. 數據中含有特殊符號,如百分號、逗號和美元符號
B. 日期和時間數據
C. 分數、二進制或八進制的數據
對於固定域數據,列模式輸入只能讀取標準數據,而格式化模式輸入則既能讀標準數據,也能讀非標準數據。
2) 格式化模式輸入
按格式化模式輸入時,INPUT語句的寫法爲:
INPUTpoint-control variable informat……;
其中,point-control爲輸入指針控制,將輸入指針移到數據域的開始位置,variable定義變量名,informat定義輸入格式。
例如:
input@1 lname $7. +1 fname $5. @15 jobtitle 3. +1 salary comm9.;
2)輸入指針控制
在按格式化模式輸入時,有兩種輸入指針控制方式:
A. @n :絕對指針控制,將輸入指針移到第n列,可以前後移動
例:對一條記錄:
----+----1----+----2----+--
EVANS DONNY 112 29,996.63
可以使用如下INPUT語句:
input@9 fname $5. @19 salary comma9. @15 jobtitle 3.;
B. +n :相對指針控制,將輸入指針從當前位置向前移n列,不能後移
例:同樣對上述記錄,可以使用如下INPUT語句:
inputlname $7. +1 fname $5. +1 jobtitle 3. +1 salary comma9.;
或 input lname $7. +1 fname $5. +5 salary comma9.;
絕對指針控制 @n和相對指針控制 +n可混合使用,例:
inputlname $7. +1 fname $5. +5 salary comma9. @15 jobtitle 3.;
或 input @9 fname $5. @1 lanme $7. +11 salarycomma9. @15 jobtitle 3.;
另外,列模式和格式化模式也可混合使用,例:
inputlname $ 1-11 @9 fname $5. +5 salary comma9.;
3)SAS輸入格式
下面我們來看SAS的輸入格式informat,它指導系統如何讀取數據。SAS系統提供許多輸入格式,上面我們用到的是最常用的一些,解釋如下:
$w. 用於讀取字符型數據,$表示是字符,w表示域寬度
w.d 用於讀取標準數字型數據,w表示域寬度,d表示小數點位數,可省略
COMMAw.d 用於讀取非標準數字型數據,COMMA是關鍵詞,w表示域寬度,
d表示小數點後位數,若數據中已包含小數點,可省略
你可以在SAS的HELP窗口中找到所有的SAS輸入格式,方法爲:
在任意窗口中,選擇:
Help à SAS System à SASLANGUAGE à SASFormats and Informats
4)記錄的格式
記錄的格式是指,在外部文件中,記錄是如何儲存的,兩種常見的記錄格式爲:
A.固定長度記錄:每條記錄的長度相同,典型的長度爲80列,例如
----+----1----+----2----+----3----+----4----+----5----……
<field1>< field2 >< field3 ><field4>…………………………
<field1>< field2 >……………………………………………………
<field1>< field2 >< field3 >……………………………………
儘管每條記錄中包含的域不同,但後面用空格填補,因而每條記錄的長度都一樣。
B.變動長度記錄:各條記錄的長度不同,例如:
----+----1----+----2----+----3----+---
<field1>< field2 >< field3 ><field4>
<field1>< field2 >
<field1>< field2 >< field3 >
由於在最後一個域後面立即就是一個結束記錄的符號,而每條記錄中的域數不同,因而每條記錄的長度不一樣。
5)有固定域數據的變動長度記錄
當讀取含有變動長度記錄的文件時,系統可能會發生誤讀錯誤,例如:
----+----1----+----2
BED/BATH 1,354.93
HOUSWEARES 2,464.05
GARDEN 923.34
GRILL 598.34
SPORTS
TOYS 6,536.53
對上述記錄,如果用下列語句讀取數據:
input dept $ 1-11 @13 totrcpts comma8.;
當讀到第三條記錄的totrcpts變量的數據時,系統在讀滿8列之前遇到記錄結束的符號,於是轉向下一條記錄,試圖完成對該變量的讀取,但GRILL是字符而非數值,因此,系統認爲該數據無效。
爲避免上述問題,對含有變動長度記錄的文件,可在INFILE語句中使用PAD選項:
INFILEfileref PAD;
PAD選項會在每條記錄填補空格,使它們具有同樣的長度。
3. ReadingDate and Time Values(讀取日期和時間值)
1)日期和時間數據
由於日期的表示方法很多,SAS系統讀入數據時必須使用輸入格式。SAS系統讀入日期和時間數據後,將其轉化爲SAS日期值,它是一個數值型變量值。你可以方便地利用SAS日期值進行排序或計算。
SAS系統用三種不同的方法將一個日期的表達轉化爲SAS日期值:
A.日期值用從1960年1月1日到這一天的天數來表示
例: 1959.1.1. ßà -365
1960.1.1. ßà 0
1961.1.1. ßà 366
B.時間值用從0點到該時刻的秒數來表示
例: 12:00 am ßà 0
12:15 pm ßà44100
5:00 pm ßà61200
C.日期時間值用從1960年1月1日0點到該時刻的秒數來表示
例: 1776.7.4. 11:30:23 ßà -5790400177
1960.1.1. 0時 ßà 0
1989.4.22.16:10:45 ßà 924883845
2)日期和時間的輸入格式
SAS系統用特別的日期和時間輸入格式讀取用不同方式表達的日期和時間數據並將其轉化爲SAS日期值。例見下表
日期表示值 |
SAS輸入格式 |
SAS日期值 |
11/05/1990 |
MMDDYYw. |
11266 |
18DEC1985 |
DATEw. |
9483 |
06-29-1958 |
MMDDYYw. |
-551 |
08:32:13.35 |
TIMEw. |
30733.35 |
你可以用格式化輸入的方法來讀取日期和時間數據:
INPUTpoint-control variable informat.;
你可以在SAS的HELP窗口中找到所有的SAS輸入格式,方法同上。
3)常用日期和時間的輸入格式
在此,我們列出一些常用的日期和時間輸入格式:
A.DATEw. 讀形如ddmmmyy或ddmmmyyyy的日期值
例:12JAN90 à date7.
12-JAN-90 à date9.
B.DATETIMEw. 讀形如ddmmmyy或ddmmmyyyy的日期後跟形如hh:mm或hh:mm:ss.ss的時間的值,日期和時間之間用空格或一特殊字符分隔
例:12JAN90/12:02:23.24 à datetime19.
12-JAN-90 12:02 àdatetime15.
C.MMDDYYw. 讀形如mmddyy或mmddyyyy的日期值
例:01/12/90 à mmddyy8.
01-12-1990 à mmddyy10.
D.TIMEw. 讀形如hh:mm或hh:mm:ss.ss的時間的值
例:12:02:23.24 à time11.
2:02 à time5.
4)YEARCUTOFF=選項
在讀取日期數據時,如果你用兩位數表示年份,SAS系統在將該日期轉化爲SAS日期值時會自動加上前兩位。自動加上的前兩位取決於SAS系統的一個選項:YEARCUTOFF=。它的缺省值是1990。例如:
04/15/00 被認爲是 04/15/1900
15APR95 被認爲是 15APR1995
YEARCUTOFF=選項決定採用兩位數表示年份時所在的100年。YEARCUTOFF=1900表示所有用兩位數表示的年份均在1900--1999之間。
你可以用OPTIONS語句或用OPTIONS窗口來改變YEARCUTOFF=選項,例如:
optionsyearcutoff=1950;
run;
該選項改變以後,用兩位數表示的年份在轉化爲SAS日期值時,其所在的100年就變爲1950-2049之間了。例如:
04/15/00 被認爲是 04/15/2000
15APR95 被認爲是 15APR1995
5)注意事項
讀取日期和時間數據時應注意以下幾點:
A.小心YEARCUTOFF=選項的缺省設置,並在必要時改變它
B.設定合適的輸入格式
C.設定合適的域寬以讀入完整的日期值
D.SAS日期值從A.D. 1582年到A.D. 20000年
E.SAS系統對閏年有調整,但忽略閏秒
6)用日期和時間值進行計算
由於SAS日期值是數值型變量,你可以用它來進行計算。例如:
data perm.aprbills;
infile aprdata;
input lname $8. @10datein mmddyy8. +1 dateout mmddyy8.
+1roomrate 6. @35 equpcost 6.;
days=dateout-datein+1;
roomchg=days*roomrate;
total=roomchg+equpcost;
run;
4. ReadingFree-Format Data(讀取自由格式數據)
1)自由格式數據
上面我們考慮的都是固定域的數據,但是包含原始數據的外部文件也很可能是自由格式的,或者說,其中的數據不是按照固定域排列的。例如
----+----1----+----2----+----3----+
ABRAMS L.MARKETING $18,209.03
BARCLAY M.MARKETING $18,435.71
COURTNEY W.MARKETING $20,006.16
FARLEY J.PUBLICATIONS $21,305.89
HEINS W.PUBLICATIONS $20,539.23
或
----+----1----+----2----+----3----+
ABRAMS*L.*MARKETING*$18,209.03
BARCLAY*M.*MARKETING*$18,435.71
COURTNEY*W.*MARKETING*$20,006.16
FARLEY*J.*PUBLICATIONS*$21,305.89
HEINS*W.*PUBLICATIONS*$20,539.23
這些域之間可能是以空格分隔,也可能用其他的分界符分隔。
2)列表輸入
自由格式數據可以簡單地用列表輸入方式讀取,因爲你無須指定數據從第幾列開始,你只需要按照數據排列的順序列出變量名即可。列表輸入的一般形式爲:
INPUTvariable $;
例如:
inputname $ age bankcard;
注意,你必須在變量名後用$符號標明字符型變量。
3)列表輸入的規則和限制
A. 域之間必須有至少一個空格或其他的分界符分隔
B. 必須按順序讀取,從左到右,不得跳過或重讀域
C. 不管對字符型或數字型變量,遺漏數據必須用一個“.”指明
D. 所有變量長度爲8,超過長度的字符型變量值被截斷,但是域的寬度可以超過8列
E. 數據必須是標準的數字型或字符型變量
F. 字符型變量不得內含空格
4)DLM=選項
如果原始數據文件中用不同於空格的分界符來分隔不同的域,你可以在INFILE 語句中用DLM=選項來設定分界符。一般形式爲:
INFILEfile-specification DLM='characters';
例如:對下列文件 Fileref:CREDIT
----+----1----+----2
MALE,27,1,8,0,0
FEMALE,29,3,14,5,10
FEMALE,34,2,10,3,3
MALE,35,2,12,4,8
用 infile credit dlm=',';
5)MISSOVER選項和遺漏數據
如果你的原始數據文件在某些記錄的最後一個或幾個域中有遺漏數據的話,你可以在INFILE 語句中用MISSOVER選項來防止系統轉到下一個記錄繼續讀取數據。一般形式爲:
INFILEfile-specification MISSOVER;
例如:對下列文件 Fileref:CREDIT
----+----1----+----2
MALE 27 1 8 0 0
FEMALE 29 3 14 510
FEMALE 34 2 10
MALE 35 2 12 4 8
用 infile credit missover;
如果你的原始數據文件在某些記錄的開始或中間的域中有遺漏數據的話,爲了要使用列表輸入,你就必須對你的原始數據文件進行編輯,用一個“.”來代替文件中的遺漏數據。例如:
----+----1----+----2
MALE 27 1 8 0 0
. 29 3 14 5 10
FEMALE . 2 10 33
MALE 35 2 12 4 8
6)LENGTH語句
如果有字符型變量的長度超過8,你可以用LENGTH語句來定義,以免被截斷。其一般形式爲:
LENGTHvariable $ length;
例如: length lname fname $ 20;
或 length lname $ 20 fname $ 15;
注意,在DATA步中,變量的屬性在當它第一次出現時確定,因此,LENGTH語句應該放在INPUT語句之前。另外,在LENGTH語句中已經定義爲字符型的變量,在INPUT語句中可以不再用$符號指明起字符屬性,當然,保留$符號也不會引起錯誤。
例如:對下列文件 Fileref:citydata
----+----1----+----2----+----3
ANCHORAGE 488081174431
ATLANTA 495039425022
PHILADELPHIA1949996 1688210
SACRAMENTO257105 275741
用: data perm.growth;
infilecitydata;
length city $12;
input city $pop70 pop80;
proc printdata=perm.growth;
run;
7)修正列表輸入
在使用列表輸入時,下面兩個格式修正符可以幫助你更方便地讀取數據:
A.“&”符號使你能讀取內含單個空格的字符型變量
B.“:”符號使你能讀取非標準數據或長於8個字符但不內含空格的字符型變量
一般形式爲:
INPUTvariable :|& informat.;
例如:對下列文件 Fileref:topten
----+----1----+----2----+
1 NEWYORK 7,262,700
2 LOSANGELES 3,259,340
3CHICAGO 3,009,530
4HOUSTON 1,728,910
5 PHILADELPHIA 1,642,900
8DALLAS 1,003,520
9 SANANTONIO 914,350
10PHOENIX 894,070
可用 dataperm.cityrank;
infiletopten;
input rankcity & $12. pop86 : comma.;
run;
注意,當你使用格式修正符“&”時,域之間必須用兩個連續的空格進行分隔。另外,由於在列表輸入時,系統以遇到分界符(空格)爲一個數據的結束,因此,對數字型變量的輸入格式 COMMAw.,你不必設定寬度w。
8)格式化輸入和修正列表輸入的輸入格式
同樣的輸入格式,在格式化輸入和修正列表輸入中,它們的實際效果是不同的。比如對上例,比較下面兩種輸入方法:
A. input @3 city$12.;
B. input rank city& $12.;
用A方法,每次讀12列,不管其中是否包含空格,而用B方法,輸入格式僅指明字符變量的長度,讀取數據時,遇到兩個連續空格時就會停止。
9)混合輸入方式
爲了方便用戶,SAS系統允許在INPUT語句中混合使用各種輸入方式。
例如:對 Fileref: rawdata
----+----1----+----2----+----3----+----4
209-20-3721 07JAN78 41,983 SALES 2896
223-96-8933 03MAY86 27,356 EDUCATION2344
232-18-348517AUG81 33,167 MARKETING 2674
251-25-939208SEP84 34,033 RESEARCH 2956
可用
data perm.mixed;
infile rawdata;
input ssn $ 1-11@13 hiredate date7. @21 salary comm6. Dept : $9. Phone;
run;
5. ReadingMultiple Records per Observation(由數條記錄讀取一條觀測)
1)一條觀測包含數條記錄
在有些原始數據文件中,SAS系統所需要的一條觀測分佈與數條記錄中,例如
Raw Data File SAS Data Set
----+----1----+---
ABRAMS THOMAS LNAME FNAME DEPT JOBCODE SALARY
MARKETING SR01
$25,209.03 --> 1 ABRAMS THOMAS MARKETING SR01 25209.03
BARCLAY ROBERT 2 BARCLAY ROBERT EDUCATION IN01 24435.71
EDUCATION IN01 3 COURTNEY MARK PUBLICATIONS TW01 24006.16
$24,435.71
COURTNEY MARK
PUBLICATIONS TW01
$24,006.16
你可以用幾個INPUT語句讀每一條記錄,來構成一條觀測:
input lname $ 1-8 fname $ 10-15;
input dept $ 1-12 jobcode $ 15-19;
input salary comma10.;
你也可以利用行指針控制,在一個INPUT語句中完成這些工作。
2)行指針控制“/”
“/”使輸入指針轉移到下一個記錄。
例如,對原始數據文件 Fileref:memdata
----+----1----+----2
LEEATHNOS
1215RAINTREE CIRCLE
PHOENIX AZ 85044
HEIDIEBAKER
1751 DIEHLROAD
ALEXANDRIA VA 22314
可用
dataperm.members;
infile memdata;
input fname $ lname $ /
address $20. /
city : $10. state $ zip;
run;
3)行指針控制“#n”
“#n” 使輸入指針轉移到第n個記錄。它能讓你以任意順序讀取這n個記錄。
例如,對原始數據文件 Fileref:memdata
----+----1----+----2----
ALEXBEDWAN
609 WILTONMEADOW DRIVE
GARNER NC27529
XM034FLOYD
ALISONBEYER
8521 HOLLYSPRINGS ROAD
APEX NC 27502
XF124LAWSON
可用
dataperm.patients;
infile patdata;
input #4 idnum $5.
#1 fname $ lname $
#3 city $ state $ zip;
run;
6. ReadingMultiple Observations per record(由一條記錄讀取數條觀測)
1)一條記錄包含數條觀測
在有些文件中,每一條記錄可能包含SAS所需要的數條記錄,它可能有以下幾種情況:
A.重複的塊
例如:
----+----1----+----2----+----3-
01FEB90 1689.45 02FEB90 2167.34
B.相同數目重複的域
例如:
----+----1----+----2----+----3
001 WALKING AEROBICS CYCLING
002 TENNIS JOGGING SWIMMING
C.不同數目重複的域
----+----1----+----2----+----3
001 WALKING AEROBICS CYCLING
002 TENNIS
003 JOGGING SWIMMING
2)讀取重複的塊
爲讀取含重複塊的記錄,你只需在INPUT語句中加入行停留符@@即可。例如:
Fileref: TEMPDATA
data perm.april90; >----+----1----+----2----+----3--
infile tempdata; 01APR90 68 02APR90 67 03APR9070
input date : date7. 04APR90 74 05APR90 72 06APR90 73
hightemp @@; 07APR90 71 08APR90 75 09APR90 76
run; 10APR90 78 11APR90 70 12APR90 69
3)讀取相同數目重複的域
重複的域的意思是說,在一個記錄中,包含一個特徵域(id field)和若干信息域,這若干信息域中所含的信息均對應於特徵域所指的對象。也就是說,SAS的一條觀測所包含的變量應由特徵域和其中一個信息域組成。
爲讀取相同數目重複的域,要使用行停留符@和DO循環及OUTPUT語句。例如:
Fileref:DATA89
data perm.sales89;
infile data89; >----+----1----+----2----+----3----+----4
input idnum 4. @; 07341,323.34 2,472.85 3,276.65 5,345.52
do quarter=1 to 4; 09431,908.34 2,560.38 3,472.09 5,290.86
input sales : comma8. @; 1009 2,934.12 3,308.41 4,176.18 7,581.81
output; 10431,295.38 5,980.28 8,876.84 6,345.94
end; 11902,189.84 5,023.57 2,794.67 4,243.35
run; 1382 3,456.34 2,065.83 3,139.08 6,503.49
4)讀取不同數目重複的域
如果在記錄中重複域的數目不同的話,可在INFILE語句中使用MISSOVER選項,同時,用DO WHILE循環代替上述的DO循環。例如:
data perm.sales89; Fileref: DATA89
1. infile data89 missover;
input idnum 4. sales : comma8.@; >----+----1----+----2----+
quarter=0; 1824 1,323.342,472.85
do while (sales ne .); 1943 1,908.34
quarter+1; 2046 1,423.521,673.46
output; 2063 2,345.34
input sales : comma8. @;
end;
run;
5)行停留符@@和@
上面我們用到了行停留符@@和@,它們的作用都是使輸入指針停留在當前記錄,也就是說,使下一條INPUT語句能在同一條記錄中讀取數據。它們都用在INPUT語句的最後,如果遇到一個最後沒有行停留符的INPUT語句,則下一個INPUT語句就從下一條記錄中開始讀取數據。它們的區別在於:
A.行停留符@@的作用比較持久,它可以在DATA步的循環中持續保持。
B.行停留符@僅在DATA步的一次循環中起作用,DATA步開始下一輪循環時,會從下一條記錄開始。
6)DO循環
DO循環可以使在DO語句和END語句之間的SAS語句重複執行。一般形式爲:
DOindex-variable specification;
More SASstatements;
END;
其中,index-variable是一個指標變量,決定DO循環的執行,條件(specification)可以是離散的,如:
doa=1,5,40;
或設定範圍的,如:
doa=1 to 5;
或 do a=10 to 100 by 10;
7)DO WHILE循環
DO WHILE循環在條件爲真時重複執行DO WHILE語句和END語句之間的SAS語句。一般形式爲:
DOWHILE (expression);
More SASstatements;
END;
在循環的頂部,檢驗expression,當它爲真時,執行循環內語句,否則,不執行。
8)SUM語句
SUM語句把一個表達式的結果加入到一個累積變量中。一般形式爲:
Variable+expression;
例如:
time+1;
balance+(-debit);
9)OUTPUT語句
OUTPUT語句將當前的觀測立即寫入SAS數據集。事實上,在每個DATA步的最後,都隱含一個OUTPUT語句。OUTPUT語句的一般形式爲:
OUTPUTSAS-data-set;
SAS-data-set是要寫入的SAS數據集名,如果與DATA語句中設定的數據集名一致的話,可省略。
7. ReadingHierarchical Files(讀取分級文件)
1)分級文件
這裏,我們所說的分級文件是指在原始數據文件中的包含這樣的結構:它由一些頭記錄,每條頭記錄後跟一條或幾條詳細記錄所組成。例如:
Raw Data File
>----+----1----+--
header P 1095
detail C 01-08-89 $45.0
detail C 01-17-89 $37.5
header P 1096
detail C 01-09-89 $156.5
header P 1097
detail C 01-02-89 $109.0
header P 1099
detail C 01-03-89 $45.0
detail C 01-05-89 $45.0
header P 1201
detail C 01-05-89 $37.0
其中,每條記錄的第一列標明,該記錄是頭記錄或是詳細記錄。基於這樣的數據文件,你可能希望對每一個詳細記錄建立一條觀測,如:
OBS PATID DATE AMOUNT
1 1095 01/08/89 $45.00
2 1095 01/17/89 $37.50
3 1096 01/09/89 $156.50
4 1097 01/02/89 $109.00
或者,對每一個頭記錄建立一條觀測,如:
OBS PATID TOTAL
1 1095 $82.50
2 1096 $156.50
3 1097 $109.00
對每一個詳細記錄建立一條觀測
爲了對每一個詳細記錄建立一條觀測,可按以下步驟進行:
A.引入確定記錄類型的變量,並在輸出時將其丟棄
B.在DATA步的循環過程中保留頭記錄的內容
C.讀取記錄中確定記錄類型的域
D.若是頭記錄,讀取記錄內容
E.若是詳細記錄,讀取記錄內容,並在數據集中寫入一條觀測
例如: Fileref: CENSUS
data perm.people(drop=type); >----+----1----+----2
infile census; H 321 S. MAINST
retain address; P MARY E 21 F
input type $1. @; P WILLIAM M 23M
if type='H' then input @3 address $15.; P SUSAN K 3 F
if type='P'; H 324 S.MAIN ST
input @3 name $10. @13 age 3. @16 gender $1.; P THOMAS H 79 M
run; P WALTER S 46 M
P ALICEA 42 F
注意,由於“ if type='P'; ”當條件不成立時,DATA步下面所有的語句都不執行,直接返回DATA步首,因此讀取頭記錄時沒有輸出。而讀取詳細記錄時,DATA步最後隱含的OUTPUT語句起作用,會輸出一條觀測到數據集中去。
對每一個頭記錄建立一條觀測
爲了對每一個詳細記錄建立一條觀測,可按以下步驟進行:
A. 引入確定記錄類型的變量,並在輸出時將其丟棄
B.定義一個變量,用於判斷是否已讀到外部文件的最後一條記錄
C.在DATA步的循環過程中保留頭記錄的內容
D.讀取記錄中確定記錄類型的域
E.若是頭記錄,判斷它是否第一條頭記錄
F.如果不是第一條頭記錄,則執行輸出(OUTPUT)語句
G.讀取頭記錄內容
H.若是詳細記錄,讀取記錄內容,並進行相應的計算
I.若已讀到最後一條記錄,則將最後一條觀測寫入數據集
例如: Fileref: CENSUS
data perm.residnts(drop=type);
infile census end=last; >----+----1----+----2
retain address; H 321 S. MAIN ST
input type $1. @; P MARY E 21 F
if type='H' then do; P WILLIAM M 23 M
if _n_ > 1 then output; P SUSAN K 3 F
total=0; H 324 S. MAINST
input address $ 3-17; P THOMAS H 79 M
end; P WALTERS 46 M
else if type='P' then total+1; P ALICE A 42 F
if last then output;
run;
4)DROP=選項
在DATA語句中的DORP=選項,可使某個在DATA步中出現的變量不被寫入SAS數據集中。一般形式爲:
DATASAS-data-set(DROP=variable);
注意,該選項用括號括起。
5)_N_變量
_N_是一個自動變量,它記錄DATA步執行的次數。
6)END=選項
在INFILE語句中設定一個END=選項可使你確定是否已讀到文件尾。一般形式爲:
INFILEfile-specification END=variable;
其中variable是一個臨時的數字型變量,當讀完最後一行時,它的值是1,在這之前,它的值爲0。同上述自動變量_N_一樣,它不會被寫入SAS數據集。
7)DO/END語句組
一般形式爲:
DO;
More SASstatements;
END;
表明一組SAS語句被當作一個單位執行。它區別於DO循環和DO/WHILE循環。一般用在IF-THEN語句中條件地執行多個SAS語句。
8)RETAIN語句
一般形式爲:
RETAINvariable;
其中,variable是你希望在DATA步的循環中保持起內容的變量名。你也可以在一個RETAIN語句中一個以上的變量,如:
retainidnum jobcode;
如果在RETAIN語句不設定任何變量,則數據集中所有變量的內容將被保留。如
retain;
9)IF-THEN/ELSE語句
一般形式爲:
IFexpression THEN statement;
ELSE statement;
其中,statement是任意可執行的SAS語句。ELSE語句爲可選,如果有的話,它必須緊接在IF-THEN語句後。
另外,一個特別的IF語句,其一般形式爲:
IFexpression;
只有當條件滿足時,DATA步剩下的語句纔會被執行,否則,回到DATA步首。
8. ReadingVariable-Length Records(讀取變動長度的記錄)
前面我們已經遇到過變動長度的記錄的讀取,但每條記錄中的域是按固定列排列的,或是在域之間有分界符隔開的。下面我們考慮以下兩種情況:
1)含有變動域寬的變動長度記錄
爲讀取含有變動域寬的變動長度記錄中的數據,DATA步的語句應包含以下幾點:
A.決定每條記錄的長度
B.用行停留符停留在當前記錄
C.從記錄長度中減去固定寬度域的寬度
D.用$VARYINGw.的輸入格式讀取變動域寬的域
例: Fileref: PHONDAT
data perm.phones; >----+----1----+----2
infile phonedat length=reclen; 1802JOHNSON2123
input idnum 4. @; 1803BARKER2142
namelen=reclen-8; 1804EDMUNDSON2325
input name $varying10. namelen 1805RIVERS2543
phonext; 1806MASON2646
run; 1807JACKSON2049
2)含有變動域數的變動長度記錄
假設每條記錄中包含不同數目的重複塊,但每個域有固定寬度,可按以下步驟讀取數據:
A.決定每條記錄的長度
B.用行停留符停留在當前記錄
C.用重複的語句讀取塊中的數據,停留在當前記錄,用OUTPUT語句輸出,直到記錄尾。
例如: Fileref: BPDATA
data perm.health;
infile bpdata length=reclen; >----+----1----+----2----+----3----
input idnum 4. @; 1234 13MAR89 120/80
do index=6 to reclen by 15; 1443 12FEB89 120/70 03FEB90 125/80
input date : date7. bp $ @; 1681 11JAN90 120/80 05JUN90 110/70
output; 2034 19NOV88 130/70 12MAY89 150/90
end;
run;
3)LENGTH=選項
一般形式:
INFILEfile-specification LENGTH=variable;
其中,variable是一個數字型變量名,它的值等於當前記錄的長度。它不會被寫入SAS數據集。
4)$VARYINGw.的輸入格式
一般形式:
INPUTvariable $VARYINGw. Length-variable;
其中,variable是一個字符型變量,$VARYINGw.設定該變量的長度,Length-variable是一個數字型變量,它指明在當前記錄中,這個字符變量的域寬。注意,在輸入格式由兩部分組成,另外,Length-variable的值應不大於w。