| 
 | 
板凳
 
 
 楼主 |
发表于 2004-4-2 13:33:25
|
只看该作者
 
 
 
3
Chapter 3: 纵合并 
3.1 追加原始文件 
 
原始数据可以使用以下的方法进行纵合并。 
 
 
INFILE语句 
 
FILENAME语句 
 
FILEVAR=选项 
 
操作系统自身的技术 
 
首先,你可能要察看原始数据。可以用FSLIST过程。 
语法: 
PROC FSLIST FILE = file-specification; 
RUN; 
 
实际使用中,专门的编辑器,如UltraEdit之类的小软件,用来察看原始文件有着更多的便利。 
 
INFILE 
为了读取多个原始文件,可以使用多个INFILE语句。这样数据步会从第一个文件中读出一条记录,再到第二个文件读一条记录,以此类推,读完所有文件再返回第一个文件。如下图所示 
 
[img:28dbf]http://sasor.feoh.net/_usrdata/images/article/sasor_column6b.gif[/img:28dbf] 
 
FILENAME 
你也可以使用FILENAME语句,对原始文件进行串联。如下图所示: 
 
[img:28dbf]http://sasor.feoh.net/_usrdata/images/article/sasor_column6c.gif[/img:28dbf] 
 
FILENAME语法如下: 
FILENAME fileref ('external-file1' 
'external-file2' … 'external-filen'); 
 
其中fileref是任何8位或以下的有效SAS名称。 
'external-file' 是数据文件的物理名。 
 
例如: 
filename Q1 ('Month1.dat' 'Month2.dat' 'Month3.dat'); 
data firstq; 
   infile Q1; 
   input Flight $ Origin $ Dest $ 
      Date : date9. 
      RevCargo : comma15.2; 
run; 
 
FILEVAR= 
使INFILE语句的FILEVAR=选项,它可以帮助你有条件的连接多个原始文件,如下图所示: 
[img:28dbf]http://sasor.feoh.net/_usrdata/images/article/sasor_column6d.gif[/img:28dbf] 
 
语法: 
infile xxx filevar = NextFile; 
 
xxx 是任意的8位或以下的占位名,不是一个实际的文件名或者定义好的文件引用。SAS使用这个占位名在日志中报告处理信息。 
NextFile 存放原始数据文件名的变量。 
 
例如: 
data movingq; 
   do I = 11,10,9; 
   NextFile = "Month"!!put(I,2.)!!".dat"; 
   NextFile = compress(NextFile,' '); 
   infile xxx filevar = NextFile; 
   input Flight $ Origin $ Dest $ Date : date9. 
      RevCargo : comma15.2; 
   output; 
   end; 
   stop; 
run; 
 
这个例程把Month11.dat, Month10.dat, Month9.dat三个原始文件装入到movingq数据集中,从中我们可以学到几点: 
1. 需要使用STOP语句跳出数据步循环。 
2. COMPRESS函数删除了字符串中的空格,使"Month 9.dat"变成"Month9.dat"。 
3. 以上程序只在每个原始文件中读出头一条记录。 
 
使用END=选项,我们可以控制数据步读完整个原始文件。 
语法: 
INFILE file-specification END = variable; 
 
END=选项把是否到达输入文件结尾标志放进variable变量中,如果当前的输入没有到达文件尾,变量值为0;反之变量值为1 
该变量不会被写入到输出SAS数据集中。 
 
由此,完整的程序为: 
data movingq; 
   do I = 11,10,9; 
      NextFile = "Month"!!put(I,2.)!!".dat"; 
      NextFile = compress(NextFile,' '); 
      do until (LastObs); 
      infile xxx filevar = NextFile end = LastObs; 
      input Flight $ Origin $ Dest $ Date : date9. 
         RevCargo : comma15.2; 
      output; 
   end; 
end; 
stop; 
run; 
 
项目中经常用到如下技巧: 
data movingq; 
   MonNum = month(today()); 
   MidMon = month(intnx(‘month’,today(),-1)); 
   LastMon = month(intnx(‘month’,today(),-2)); 
   do I = MonNum, MidMon, LastMon; 
      NextFile = "Month"!!put(i,2.)!!".dat"; 
      NextFile = compress(NextFile,' '); 
      do until (LastObs); 
         infile xxx filevar = NextFile end = LastObs; 
         input Flight $ Origin $ Dest $ Date : date9. 
            RevCargo : comma15.2; 
         output; 
      end; 
   end; 
   stop; 
run; 
 
以上程序读出当月和之前两个月的原始数据。这里的重点是INTNX函数,如果我们直接用当前月-1,-2来得到前两个月,在1,2月时程序就会发生错误。INTNX作用是返回间隔某个时间端的时间。函数格式为: 
 
INTNX('interval',start-from,increment) 
 
'interval' 一个字符常量,或者是存放时间间隔单位的变量。表示间隔单位。 
start-from 表示日期,日期时间或者时间的SAS表达式,作为起始点。 
increment 一个正或者负整数,表示时间间隔的数量。 
函数细节可以查询SAS在线帮助。 
 
题外话,与考试无关。项目中用的更多的是读出一个路径下的同一类接口文件,简便方法是使用如下FILENAME。 
FILENAME cf_list PIPE 'dir c:|rawdata|cf????.dat /b'; 
DATA cf_data; 
   INFILE cf_list; 
   LENGTH filename $20; 
   INPUT filename $; 
   INFILE in FILEVAR = filename END = LastFile; 
   DO WHILE (LastFile = 0); 
      INPUT .... 
         .... 
      ; 
      OUTPUT; 
   END; 
RUN; 
这段程序把c:|rawdata下面的所有cf0101.dat,cf0102.dat,...,cf????.dat读入cf_data数据集中。如果看不明白,说明以上的内容你还没有全部理解 <!-- s:-) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":-)" title="Smile" /><!-- s:-) --> |   
 
 
 
 |