index: output put replace file infile
沒人任何規定的輸出語句,sas系統會輸出pdv當前觀測到主數據集原先的位置
output語句:
TIPS:
1:當output沒有規定數據集名字時,把當前觀測《也就是一行數據》輸出到data步后面的所有數據集的末尾<注意是所有數據集>意味着縱向合並,當規定數據集名字時,把pdv當前觀測輸出到output規定的數據集末尾。
2:在有output語句和run語句同時存在的data步里面,pdv只會執行output的結果到正在被創建的數據集,而執行run語句的結果是pdv會清空所有的變量為缺失。
3:如果一個output語句出現在程序語句中間,無論有沒有被執行,后面的語句都將繼續被執行,但是不會輸出結果到正在被創建的輸出數據集,而是會持續清空pdv中所有變量值(使用retain性質的語句除外).
4:sas中有implicit output和explicit output,在每一輪data循環后,sas會默認的將pdv中的數據寫入數據集,這就是implicit output,還有一類是用戶明確寫的output語句,也就是explicit output,當明確規定后,隱式的output就不會再執行了。
5:output是將數據輸入數據集,put是將數據輸入文件或日志
*需求:輸出by組的最后一行觀測值並將上一行的y值輸出;
data a; input x y@@; cards; 1 10 1 20 1 200 2 30 2 40 3 50 3 60 4 70 3 80 4 400 ; run; proc sort data=a;by x;run; data res; set a; by x; retain rt; *如不用retain,下面的put能輸出正確的值,但是運行到run后會自動清空,這樣output的結果集中rt都會為缺失值; if first.x then rt=0; if last.x then output; rt = y; put rt=; run; proc print data=res noobs;
*由一個輸入數據行輸出多條觀測;
data a; input id x1-x3; cards; 101 10 20 30 102 40 50 60 ; run; data b; set a; x = x1; output; x = x2; output; x = x3; output; output; run;
data c1 c2;*根據條件選擇輸出;
set sashelp.class;
if _n_ le 7 then output c1;
else output c2;
run;
*輸出每個by組的最后一條觀測和倒數第二條的y值;
data a; input x y@@; cards; 1 10 1 20 1 200 2 30 2 40 3 50 3 60 4 70 3 80 4 400 ; run; proc sort data=a;by x; run; data b; set a; by x; retain rt; if first.x then rt=0; if last.x then output; rt = y; run;
/*讀入第一條觀測值時,rt被置為0,last.x為0不執行,rt=10,執行run,retain的rt保留在pdv中,因為output和run同時存在時run不會輸出數據,只有output執行的時候rt才會被輸出
,當讀入第二條觀測的時候output也不執行,但是這時的rt是保留的第二條觀測值的y,當讀入第三條觀測的時候output執行,順便輸出pdv中的rt,這時的rt是倒數第二條觀測值的rt,還沒有進行賦值*/
remove語句
remove和delete和if子句都能起到獲取部分數據集的效果,但是delete和if都perform only on physical但是remove既可以logical也可以physical,對於不同的引擎。
replace語句:
REPLACE <data-set-name-1> <...data-set-name-n>;
如果不加則為輸出pdv當前觀測到數據集原先位置。該語句是系統的默認語句,只能在modify語句中使用
使用replace-->>log日志:已更新數據集 WORK.STOCK。重寫了 10 個觀測,添加了 0 個觀測,刪除了 0 個觀測。並不會添加或刪除,只會重寫
4:remove:當pdv輸出當前觀測到主數據集原先位置后,remove語句刪除該觀測值,該觀測值可以使物理也可以是邏輯的
,只能在modify語句中使用。
自動變量_IORC_
當運行modify語句時,系統會自動創建一個_iorc_變量,其包含系統每次運行modify語句時返回的i/o操作碼
以匹配訪問為例:
如果主數據集by變量值在更新數據集中存在,則返回0
不存在,則不產生自動變量_iorc_
如果更新數據集by變量在主數據集中不存在,則返回一個非零值。
PUT輸出(默認輸出到log窗口)
data me; input x$ y z m n p q; cards; a 10 20 30 40 50 60 b 70 80 90 100 110 120 ; run; data _null_; set me; put @2 x$ @; *@2放在變量前表示從第二列開始輸出 @在變量后表示數據指針繼續停留在當前行輸出; put +3 y 6-10 .2@; *+3表示變量y在x的3列后輸出,這里用到了6-10的固定列輸出方式,只是為了展示用,如果將6-10寫成2-10則會發現覆蓋掉了x的值, .2表示輸出y時的表示方式有小數點后加2位小數; put +5 z: 10.2@; * :一定要寫在 10.2前面,這表示去掉z與m之間多余的空格; put +5(m n p)(best10. "--" 4.2 "--" 4.2)@; *這里使用的是列表方式的數據 前面括號中的變量和后面括號中的格式一一對應 best10.是sas獨有的輸出方式,sas系統會以最列總數10的適合的方式輸出m的值; put +10 q=; *命名方式輸出,輸出結果會帶等號; run;
file語句
filename Outfile 'C:\Users\Administrator\Desktop\sas-test\utf.txt';*定義輸出的文件名和路徑,本來打算用outputfile來定義filename的,結果編譯失敗,應該是名字過長的原因;
*filename只能定義一個輸出文件;
data _null_;
set sashelp.class;
file Outfile encoding='utf-8'; *定義輸出的編碼格式;
put name weight; *file一般和put連用,put語句會把后面的變量put進文件中;
run;
data a;
length temp $50; *規定文件名長度,不然會輸出過短,系統默認字符長度只有8位;
file Outfile filename=temp; *filename=選項獲取文件名的字符串;
put 'abc'; *輸出abc到outfile中;
fname = temp; *a只有一個變量,fname;
run;
*動態定義多個輸出文件;
data me;
length name $200;
input name;
*其機制和set語句相同,input執行時,跳轉到cards語句,按你定義的方式讀取input后面的變量的值,這里是整行整行讀取,讀取玩一行后跳轉到input的下一行;
name='C:\Users\Administrator\Desktop\sas-test\'||strip(_infile_)||'.txt';
/*_infile_和_N_一樣是自動變量,可以認為后者是觀測值序號,前者是觀測值 _infile_是當前pdv中的所有值
In a DATA step, if the STRIP function returns a value to a variable that has
not previously been assigned a length, then that variable is given the length of the argument
說白了就是去前后空格的意思,好讓文件名路徑正確*/
file anyname filevar=name;
date =date();
n = name;
format date yymmdd10.;*固定date的輸出格式;
do; *do end循環輸出內容到文件中;
put 'test'@;
put ','@;
put date;
end;
cards;
test_file1
test_file2
test_file3
;
run;
/*輸出數據集到文件,添加表頭和尾,並規定輸出格式*/
data _null_;
set sashelp.class(keep = name sex) nobs=obs end=last;
file 'C:\Users\Administrator\Desktop\sas-test\test.txt';
date = date();
if _n_ = 1 then
do;
put 'header '@;
put date @; format date yymmdd10.;
put obs z2.;
end;
do;
put name $ 1-10 @;
put sex 15-16;;
end;
if last then do;
put 'end';
end;
run;
data _null_;
set chapt3.file_put1;
file 'C:\Users\Administrator\Desktop\sas-test\test.txt' dropover lrecl=32767 dsd dlm=';'; *dlm選項是分隔符,代表輸出文件用到的分隔符 dsd表示將變量本身包含的一些敏感符號用雙引號括起來,以免和分隔符發生沖突;
*不定長輸出;
do;
put firtname @;
put id @;
put phonenumber ;
end;
do;
put firstname $10. @;
put ','@;
put id $3. @;
put ',' @;
put phonenumber 8.;
end;
run;
INFILE語句
data a; infile datalines missover; *missover是缺失值的解決發難,會在相應的位置上打點; input x1-x4; *infile中 dsd除了和file中的dsd意思一樣還默認用逗號為分隔符; datalines; 97.2 98.2 96.5 9 5 4 4 2 41 5 ; run;
幾個選項的解釋 lrecl規定文件的邏輯記錄長度,也就是一行的長度。