1 讀取雜亂的原始數據(列指針+冒號修飾符)
當原始數據中沒有排列整齊或無法預知要讀取的字符長度時,三種輸出樣式及其混合都無法完成讀取。這時就需要借助更多的工具:@'character'列指針 和 冒號修飾符。
列指針
列指針有兩種用法:
- @n:n指SAS要移動到的列
- @'character':character指SAS要移動到的特定字符或者單詞
@'character'列指針能在讀取數據之前,將指針移動到指定的列。然而,有時候我們並不知道數據開始位置,若知道數據總是在一個特定的字符或者單詞之后開始,這種情況就能使用@'character'列指針。
狗的品種信息總是出現在單詞breed之后,示例:input @'breed:' dogbreed $;
冒號修飾符
字符變量的默認長度是8個字符。則讀取變量時有幾種可能情況:
- 字符變量長度 ≤ 8,讀入語句運行良好
- 字符變量長度 > 8,只能讀入長度 ≤ 8的數據,其他會丟失
- 若指定輸出格式,如($20.),則讀入變量可能會包含不需要的字符
為避免遇到上面問題,可以在輸入格式使用冒號修飾符:在輸入格式前面放置一個冒號。這樣就能告知SAS讀取到輸入格式的長度 或 直到遇到分隔符就終止,二者以先遇到者為准。
示例::$20.
以變量值rottweiler為例,下表是幾種不同input語句得到的結果:
| input語句 | 描述 | 變量dogbreed的值 |
|---|---|---|
| input @'breed:' dogbreed $; | 默認字符變量長度為8個字符 | rottweil |
| input @'breed:' dogbreed $20. ; | 指定字符變量長度為20個字符 | rottweiler vet bill |
| input @'breed:' dogbreed :$20. ; | 冒號修飾符 | rottweiler |
2 為每個觀測讀取多行原始數據(行指針)
有的時候,一個觀測的數據分散到了多行中,這時就需要顯式告訴SAS何時換行,進入下一行繼續讀取。
行指針
在input語句中加入行指針,即可實現為單個觀測讀取多行原始數據。行指針有兩種表示方法:
- 斜線(/):跳到下一個原始數據行,簡單
- 井號n(#n):跳到指定行號的原始數據行,更靈活
示例:
input city $ state $
/ NormalHigh NormalLow
#3 RecordHigh RecordLow ;
3 從每行原始數據讀取多個觀測(雙尾@)
無論數據以何種形態存在,總會經常出現這種情況,一行原始存在多個觀測,這時需要在input語句結尾處使用雙尾@符號。
雙尾@
即(@@),其作用是讓SAS停留在那行數據,繼續讀取觀測直到數據讀取完畢,或者遇到了沒有雙尾@符號的input語句為止。
示例:input city $ state $ NormalRain MeanDaysRain @@ ;
4 讀取原始數據文件的一部分(單尾@)
當我們只需要讀取一個比較大數據文件中的一小部分,這時就需要進行選擇性讀入,只讀入需要的變量以確定是否保留當前的觀測,然后用單尾@符號結束input語句。
單尾@
單尾@符號的作用是,告訴SAS保持那行原始數據。通常,在單尾@保持該數據行時,可以使用if語句來測試該觀測,以查看它是否是你要保留的觀測。如果是,你可以使用第二條input語句,為其余變量讀取數據。
單尾@(@)和列指針(@n)非常相似,@n是告訴SAS移動到指定的列;而單尾@則像是在告知“敬請期待,請勿換台”,SAS將保持住該行數據直到data步結束,或者遇到一個沒有單尾@的input語句為止。
示例:
input type $ @ ;
if type = 'surface' then delete ;
input name $ 9-38 amtraffic pmtraffic ;
這里有3條語句:
- 第一條input語句:讀取字符變量type ,並保持該行數據
- if語句:對保持的數據進行測試
- 第二條input語句:讀取name 、amtraffic 、pmtraffic 三個變量
運行邏輯是:若一個觀測的type變量值是surface,則第二條input語句不會執行,這樣就不會將不需要的觀測添加到想要的數據集中取。
行固定標識符
單尾@和雙尾@都是SAS中的行固定標識符。區別在於它們保持一行輸入數據的時間長短不同。
- 單尾@:為后續的input語句保持一行數據,但是當SAS回到data步的頂部開始生成下一條觀測時,它將釋放那行數據
- 雙尾@:即使在SAS開始生成新觀測時,也為后續的input語句保持那行數據
兩種的共同點是,當SAS遇到了沒有行固定標識符的后續input語句時,改行數據都會被釋放。
