通过示例学SAS(1)--从外部文件读入数据

1.设在路径:c:"books"learning下有文本文件mydata.txt,其数据以空格格开,形式如下:

M 50 68 155
F 23 60 101
M 65 72 220
F 35 65 133
M 15 71 166

读入SAS的代码如下:

data demographics;
infile 'c:"books"learning"mydata.txt';
input Gender $ Age Height Weight;
run;

符号$ 表示变量Gender为一字符型变量。为了检查读入文件是否正确,可以通过Print过程察看其观测值。

title "Listing of data set DEMOGRAPHICS";
proc print data=demographics;
run;

若源文件中的数据有缺失值怎么办?比如说mydata.txt的数据内容如下

M 50 68 155
F 60 101
M 65 72 220
F 35 65 133
M 15 71 166

当SAS读到第二行时,会以60代表年龄,101代表身高。接下来会以下一行M代表体重,而M是一字符型变量。叮当,SAS在Log中报错了。正确的方式为,以 . 代表缺失值。如下图

M 50 68 155
F  .    60 101
M 65 72 220
F 35 65 133
M 15 71 166

2.读入CSV格式文件。

无需废话,看代码

data demographics;
infile 'c:"books"learning"mydata.csv' dsd;
input Gender $ Age Height Weight;
run;

DSD(delimiter-sensitive data)有几个作用。其一,表明以逗号分隔数据;其二,在一行中若有两个逗号,表明在中间有一个缺失值;其三,若字符型变量置有引号,则可以去掉其引号。上述代码的另一种形式为

filename preston 'c:"books"learning"mydata.csv';
data demographics;
infile preston dsd;
input Gender $ Age Height Weight;
run;

变量demographics是实际文件名字的别名。

如果csv格式文件不是以逗号分隔开,怎么办?例如下述文件以冒号分隔数据

M:50:68:155
F:23:60:101
M:65:72:220
F:35:65:133
M:15:71:166

读入此文件时,使用下述形式

infile 'file-description' dlm=':' ;或者infile 'file-description' delimiter=':';

如果数据是以TAB隔开呢?事情有点麻烦,但还在控制中。此时以十六进制字符代表TAB,例如

对于ASCII文件,infile 'file-description' dlm='09'x;

对于EBCDIC文件,infile 'file-description' dlm='05'x;

3.读入固定列--方式1:列输入

许多数据是以固定列(fixed columns)的形式保存在文件中。读入此种文件可以列输入(column input)的方式读入。这种方法可以读入字符型变量,格式化数字。格式化数字,不仅是正负形式的数据,还有指数形式的数值。比方说3.4E3表示3.4*10^3.

假设有如下形式的数据,保存在bank.txt中。

00110/21/1955M 1145
00211/18/2001F 18722
00305/07/1944M 123.45
00407/25/1945F -12345

没有任何分隔符。怎么办,看代码

data financial;
infile 'c:"books"learning"bank.txt';
input Subj $ 1-3
      DOB $ 4-13
     Gender $ 14
      Balance 15-21;
run;

方式2.格式化输入(Formatted input)

当数据是非标准化形式存放时,就应当考虑格式化输入方法了。还是以上面的例子为例,格式化输入的代码为

data financial;
infile 'c:"books"learning"bank.txt';
input @1 Subj $3.
       @4 DOB mmddyy10.
       @14 Gender $1.
       @15 Balance 7.;
run;

符号@称为列指针(Column Pointer),@4就是告诉SAS,指到第4列。有两种格式化形式,w.d和$w。w告诉SAS有几列数据需要读取,d表示小数点在其值的位置。例如,以3.0形式读入123,SAS会保存为123.0,对同一数字以3.1读入,SAS会保存为12.3.如果需读入的数字本身有小数点,则d将会被忽略。如以4.1的形式读入1.23,SAS仍会保存为1.23.而$w表示将读入w列数据。

需要读入日期数据时,MMDDYY10.告诉SAS以mm/dd//yyyy的形式读入日期,SAS会以1960年1月1日为起始日到此日期的天数保存。所以,如果读入01/01/1960,SAS会保存为0.

执行上述代码后,显示的数据为

 Obs      Subj     DOB     Gender      Balance     
1      001     -1533     M     1145.00     
2      002     15297     F     18722.00     
3      003     -5717     M     123.45     
4      004     -5273     F     -12345.00     

此时生日均被显示为离1960年1月1日的天数。如果想以常规形式显示,将日期重新进行格式化输出

title "Listing of FINANCIAL";
proc print data=financial;
format DOB mmddyy10.
         Balance dollar11.2;
run;

结果显示为

Listing of FINANCIAL
Obs Subj DOB Gender Balance
1 001 10/21/1955 M $1,145.00
2 002 11/18/2001 F $18,722.00
3 003 05/07/1944 M $123.45
4 004 07/25/1945 F $-12,345.00

4.使用Format表达式

假设有一份文件,其数据被空格或逗号隔开,字符长大于8字节。读入时,在Input表达式中紧随变量名后,附上格式形式。中间以冒号隔开。

例如,设有一份CSV文档,其内容如下

"001","Christopher Mullens",11/12/1955,"$45,200"
"002","Michelle Kwo",9/12/1955,"$78,123"
"003","Roger W. McDonald",1/1/1960,"$107,200"

看代码:

data list_example;
infile 'c:"books"learning"list.csv' dsd;
input Subj   : $3.
       Name  : $20.
       DOB   : mmddyy10.
       Salary : dollar8.;
format DOB date9. Salary dollar8.;
run;

另外一种使用Informat表达式的读入数据形式,是显式地使用Informat.上述读入代码可以为

data list_example;
informat Subj $3.
           Name $20.
           DOB mmddyy10.
           Salary dollar8.;
infile 'c:"books"learning"list.csv' dsd;
input Subj
       Name
       DOB
       Salary;
format DOB date9. Salary dollar8.;
run;

如果前述CSV文件中的数据是以空格隔开,且字符没有引号。例如

001 Christopher Mullens 11/12/1955 $45,200
002 Michelle Kwo 9/12/1955 $78,123
003 Roger W. McDonald 1/1/1960 $107,200

问题就来了。名字中的空格会使用SAS以为变量已结束,导致读入不正确。

问题的解决之道在于以&代替冒号:,读入的代码为

data list_example;
infile 'c:"books"learning"list.txt';
input Subj  : $3.
     Name  & $20.
     DOB   : mmddyy10.
     Salary : dollar8.;
format DOB date9. Salary dollar8.;
run;

posted on 2008-08-22 16:12  zgw21cn  阅读(4817)  评论(0编辑  收藏  举报

导航