SAS入门教程10-1-读取数据

标签:
数据读取教育 |
分类: sas编程 |
数据步读入原始数据时,要使用INPUT、DATALINES和INFILE语句的组合。
5.1
原始数据一般分为字符和数值两种类型,数值数据又分为标准数值数据和非标准数值数据。
5. 1.1标准数据
标准数据是由字符或数值组成的、可以被列表、列、格式化、命名输入方式读入的数据。如ARKANSAS,1166.42。
5.1.2非标准数据
非标准数据是只能在输入格式的帮助下读入的数据。如非标准的数值数据,可能包含逗号、空格等符号、日期和时间数值、十六进制和二进制数值。
5.1.3数值数据
标准数值数据只包含数字、小数点或负号。
非标准数值数据则包含其他的特殊字符,如千分号(‰)、美元符号($)等,用DATA步读取时,需要用格式化的INPUT语句。非标准的数值如1,220。
数值数据有多种表现形式,SAS可以直接读入标准的数值数据。非标准的数值数据则需要通过规定输入格式读入。相关的输入格式及其读取方式可参见SAS帮助文档或表5.1。
表5.1
|
数据示例 |
说明 |
读取方式 |
标准的数值数据 |
23 |
右对齐 |
|
23 |
无对齐 |
|
|
23 | 左对齐 |
|
|
00023 |
首位有字符零 |
|
|
23.0 |
有小数位 |
|
|
2.3E1 |
科学计数格式 |
|
|
-23 |
带有负号的数值 |
|
|
非标准的数值数据 |
2 3 |
数字中间有空格 | COMMA.或BZ. |
- 23 |
数字和字符之间含有空格 | COMMA.或BZ. | |
2,341 |
千位符,逗号 | COMMA. | |
(23) |
括号 | COMMA. | |
C4A2 |
十六进制 | HEX. | |
1MAR90 |
日期值 | DATE. | |
不合法的数值数据 |
23- |
减号在数值后面 | 将减号放在数值前面或利用程序将句号视为缺失值,或在INPUT语句中指定所有不合法的数值数据都为缺失值 |
... |
双句号 | ||
J23 | 非数值 | 当作字符数据读入,或修改原始数据 |
读取数值数据的规则:
·数值前面的括号或者减号符号表示该数值为负;
·首位有一个或者多个零不影响对相应变量的赋值,SAS不把数值尾部的空格默认为0;
·数值数据的前后都可以有空格,但是数字中间不能有(除非用COMMA.或BZ.格式读入)。
5.1.4
字符数据是由一系列字符组成的数据。下面任一种情况下,INPUT语句认定读入变量的值是字符值:
·INPUT语句中变量名后跟一个美元符号$;
·使用字符输入格式;
·要读入数据的变量已经被定义为字符值。
字符变量可以包含任何字符。读入包含空格和分号的原始数据时,可参照表5.2中的方法。
表5.2
包含字符 |
读入方式 |
理由 |
保存字符值开头或者结尾的空格 | 格式化输入和$CHARw.输入格式 | 列表INPUT读入方式忽略字符值前后的空格 |
数据中包含分号 | DATALINES4或CARDS4语句和4个分号(;;;;)标记数据结束 | 使用普通DATALINES或CARDS语句时,数据行中的一个分号是整个数据行的结束 |
数据中包含分隔符、空格字符或引号的字符串 | 使用DSD选项,INFILE语句加入DELIMITER=选项 | 可以使SAS读入引号中包含分隔符的字符值,同样可以将两个连续的分隔符处理成一个缺失值 |
注意:
·在DATA步中,若只在INPUT语句指定的变量后加美元符号($),则读入的是该数据的原始形态,若想读入大写字母,可以使用系统选项CAPS或$UPCASE格式。
·当读入的字符数据长度小于指定的变量长度值时,在数据的末尾添加空格以达到规定长度。
5.2
原始数据的呈现形式一般分为呈现在SAS编辑窗口的数据行和储存在外部文件中的原始数据。
1. 编辑窗口中的数据行
例5.1
data weight;
input PatientID $ Week1 Week8 Week16;
loss=Week1-Week16;
datalines;
2477 195 177 163
2431 220 213 198
2456 173 166 155
2412 135 125 116
;
run;
2. 外部文件中的原始数据
例5.2 储存在外部文件中的原始数据,TXT文本格式。
---------1----------2
2477 195 177 163
2431 220 213 198
2456 173 166 155
2412 135 125 116
5.3
原始数据根据来源不同会有不同的记录格式,为了将各种格式的原始数据通过数据步写入SAS数据集,需要使用INPUT语句的5种输入方式和混合输入方式。
INPUT语句的用途有两个方面:
·读入外部数据文件中的数据;
·读入CARDS语句后面的数据。
5.3.1
INPUT语句中描述一个记录值有以下5种方式:
1. 简单方式
INPUT <specification(s)> <@ | @@>
2. 列方式
INPUT variable<$> start-column<-end-column> <.decimalplaces><@|@@>;
3. 格式化方式
INPUT <pointer-control> variable informat.<@ | @@>;
INPUT <pointer-control> (variable-list) (informat-list)<@ | @@>;
INPUT <pointer-control> (variable-list) (<n*> informat.) <@ | @@>;
4. 列表方式
INPUT <Pointer-control> variable<$> <&> <@ | @@>;
INPUT <pointer-control> variable<: | & | ~> <informat.><@ | @@>;
5. 命名方式
INPUT <pointer-control> variable=<$><@ | @@>;
INPUT variable=<$>start-column<-end-column> <.decimals><@ | @@>;
INPUT [pointer-control> variable=informat. <@ | @@>;
选项说明:
specification(s) |
变量及其格式的详细说明 |
variable-list | 列出要读入数据值的变量 |
@ | 执行下一个INPUT语句时指针移到下一记录行,要求一条记录必须对应一个数据行 |
@@ | 执行下一个INPUT语句时指针保持在当前记录行,不要求一条记录对应一个数据行 |
$ | 定义字符型变量 |
start-column | 规定变量值在记录行中的起始列 |
end-column | 规定变量值在记录行中的终止列 |
decimalplaces | 小数点位置 |
pointer-control | 移动输入指针到指定的行或列上 |
informal | 列出变量的输入格式 |
informat-list | 列出变量列表对应的输入格式列表 |
decimals | 规定小数部分的位数 |
5.3.2列方式输入
列输入方式是用来读入严格按列排好的标准数据。
1. 列方式输入语句格式
naw-variable<$>start-column<-end-column> <.decimalplaces><@ | @@>;
设定变量名称,<>为可选项,如果选择$,则表示这是一个字符变量。而start-column<-end-column>表示该变量在记录行中的起始列和终止列。
例5.3
例中,规定记录行的第1到10列为变量NAME的输入值,11列为变量SEX的输入值,12到13列为变量AGE的输入值。NAME和SEX为字符变量。
2. 列方式输入的使用条件
·原始数据输入值的位置在每个记录行相同的列中;
·原始数据输入值是标准的数值格式或一般的字符格式。
3. 列方式输入的特点
·原始数据输入值可以按任意顺序读取;
·字符型原始数据中间可以有空格;
·可以重复读取原始数据记录行的某一部分;
·读入的数据值不需要用空格或者其他分隔符隔开。
例5.4 任意顺序读取和重复读取。
input first 73-80 second 10-12;
input id 10-15 group 13;
4. 列方式输入下的缺失值和空格
·空格和点(.)都作为缺失值处理;
·忽略值域开头和结尾部分的空格。
5.3.3列表方式输入
列表方式输入要求INPUT语句按读入数据的顺序设定变量名称,SAS通过扫描数据行来确定下一个数据值并忽略两侧多余空格。列表方式输入不要求数据在特定的列中。列表方式下的分隔符默认为空格,在没有改变分隔符的情况下,必须确保相邻数据之间至少有一个空格。列表方式输入不会跳过任何数据值来读取后面的数据,但会忽略句号后的所有数据。通过指针控制可以改变读入数据的顺序。
用列表方式输入时,系统扫描整个数据行而不是从某些特殊的列读取数据。
1. 列表方式输入
简单列表方式输入INPUT <pointer-control> variable<$><&>< @ | @@>;
调整列表方式输入INPUT <pointer-control> variable [: | & | ~ informat.><@ | @@>;
2. 列表方式输入使用条件
·相邻输入数据值之间至少有一个空格隔开;
·用小数点表示缺失值;
·字符型值的默认长度为8B,也可以用LENGTH,ATTRIB,INFORMAT语句规定长度;
·数据必须是字符数据或标准的数值数据。
3. 列表方式输入格式修饰符
列表方式输入语句中的格式修饰符有3个:“:”、“~”、“&”。下面分别介绍这3种格式修饰符。
“:”
当原始数据是以空格为分隔符时,要想为变量值长度不一致的变量指定统一的长度,就必须使用该格式修饰符。规定变量值是从非空格列中读取,直到第一次遇到以下3种情况之一,该变量值的读取过程才结束。
·下一个空格列;
·达到变量预先设定的长度(若未预先设定变量长度则为SAS默认字符长度8B);
·数据行结束。
例5.5 空格为分隔符时,对变量值长度不一致的变量规定统一的长度。
data a;
input univ : $12. Plc $ Zip;
*input univ $ Plc $ Zip;
*input univ $12. Plc $ Zip; *读数据出错;
cards;
MITBoston100023
TsinghuaUniv
run;
例中,第一个观测变量Univ的值为MIT(只读3个字符,因遇到空格而结束),第二个观测值为TsinghuaUniv(得到先前定义的变量长度12)。如果只对变量Univ规定长度,而不加格式修饰符(:),在读入第一条记录时就会出错,如果不对变量Univ规定长度,读入第二条记录时就会只读入Tsinghua,而不是预期读入的TsinghuaUniv。这是因为SAS默认的字符变量的存储长度就是8B。
“&”
字符型输入值可能包含一个或几个空格,因为空格是列表读入方式下默认的分隔符,所以如果要读入的数据值本身包括空格,就必须用此格式修饰符。
例5.6
data a;
input name & $12. age;
*input name $12. age; *读数据出错;
cards;
Jiang Zhu
Annie Zheng
I.Altman
;
run;
例中,第一个观测的name中Jiang Zhu(包含一个空格),第二个观测为Annie Zheng(包含一个空格)。分隔符为两个空格。
注意:因“&”有以上特性,故相邻数据之间应该用一个以上的空格作为分隔符。
“~”
规定读入字符值时保留引号。此选项只在INFILE语句中与选项DSD一起使用时才有效。
注意:DSD选项在第6章会有详细介绍,这里先说明它的4个功能:
·将默认分隔符改为逗号;
·对于连续的两个分隔符,中间按缺失值处理;
·将字符变量值的引号去掉;
·对引号里的分隔符按字符来看待。
所以INFILE语句中的DSD选项自动把数据记录的分隔符设置为逗号,并且读入数据之前,把字符数据中的引号去掉。若加上“~”就会保留数据中的引号。
可以通过下面的这个例子来理解DSD和“~”的作用。
例5.7
data topics2;
infile datalines dsd;
input speakers : $15. title ~ $40. location & $10.;
datalines;
Song, "Credit Derivatives", Room 329
Zhu, "Credit Risk Management", Room 406
;
proc print;
run;
由上例可以看出,虽然title变量的长度是40,而观测值的长度都不到40,仍然可以得到正确结果。可见,格式修饰符“~”包含了格式修饰符“:”的功能。把speakers后面的“:”改成了“~”也可以。例如:
data topics2;
infile datalines dsd;
input speakers ~ $15. title ~ $ 40. location & $10.;
datalines;
Song, "Credit Derivatives", Room 329
Zhu, "Credit Risk Management", Room 406
proc print;
run;
输出窗口信息为
Obs | speakers | title | location |
1 | Sang | "Credit Derivatives" | Room 329 |
2 | Zhu | "Credit Risk,Management" | Room406 |
但是,若把title后面的“~”改成“:”,引号就因为dsd选项的存在而被去掉,如下。
data topics2;
infile datalines dsd;
input speakers : $ 15. title : $ 40. location & $10.;
datalines;
Song, "Credit Derivatives", Room 329
Zhu, "Credit Risk Management", Room 406
proc print;
run;
输出窗口信息为
Obs | speakers | title | location |
1 | Sang | Credit Derivatives | Room 329 |
2 | Zhu | Credit Risk,Management | Room406 |
5.3.4
格式化输入方式是INPUT语句读取非标准数据的唯一方法。即在变量名后面规定输入格式。这种输入方式不仅给出了该输入数据所对应的类型,而且给出了输入数据所在列的长度。简单的格式化输入方式要求变量与其对应的原始数据输入值的排列顺序一致。如果想按照其他顺序读入原始数据,则需要使用指针控制。
1. 格式化方式输入
INPUT <poiter-control] variable informat. <@ | @@>;
INPUT <pointer-control>(variable-list,(informat-list) <@ | @@>;
INPUT<pointer-control>(variable-list) (<n*> informat.),<@ | @@>;
其中:
n*规定在输入列表中后面的输入格式重复n次。
例5.8
data a;
input (X1-X5) (3 * 7.2, 2 * 5.2);
datalines;
1000.122000.233000.3410.1220.23
;
run;
*或者;
data a;
input (X1-X3) 3 * 7.2 (X4-X5) (2 * 5.2);
datalines;
1000.12 2000.23 3000.34 10.12 20.23
;
run;
例中,前3个变量X1-X3的格式为7.2,而后2个变量X4-X5的格式为5.2。
例5.9 读入非标准数据$1,…,22。
data a;
input x Comma9.2;
datalines;
$1,000.22
;
run;
例中,读入的数据为1000.22,要注意长度,该数据符号加上数字一共是9列。
2. 分组格式表
分组格式表含有两个列表,每个都括在括号里。第一个指明变量,第二个给出输入格式。
例5.10
input (s1-s5)
(4.);
input (a b) ($, 5.);
input (a b) ($5.);
input (name s1-s5) ($10. 5*4.);
data scores;
input (name score1-score5) ($10. 5*4.)
*以上语句等效于以下任何一句;
*input name $10. (s1-s5) (4.);
*input (name s1-s5) ($10. 4. 4. 4. 4. 4.);
*input (name s1-s5) ($10. 5*4.);
datalines;
Whittaker 121 114 137 156 142
Smythe
;
run;
3. 格式化方式输入特点
格式化方式输入对缺失值的处理根据输入格式而定。SAS一般默认空格是字符数据的缺失值,句号是数值数据的缺失值。而其他输入格式对于缺失值的处理则不同,比如$CHAR.w把空格作为数据值的一部分,BZ.w则把空格当作零来处理。
注意,在INPUT语句中设定的输入格式并不存储在所创建的SAS数据集中,而在INFORMAT或ATTRIB语句中设定的输入格式则会被永久存储。
5.3.5
如果数据行中含有变量名,后跟等号和变量值,则读取数据时应该使用命名输入方式。
1. 命名方式输入语句格式
INPUT <pointer-control>variable=<$> <@ | @@>;
INPUT variable=<$>start-column <-end-column><.decimals> <@ | @@>;
INPUT <pointer-control>variable=informat. <@ | @@>;
其中:
Variable=规定用于INPUT语句读入的变量名。
2. 命名方式输入的使用条件
在INPUT语句的使用过程中,有时可以混合使用命名方式输入和其它方式输入。
需要注意的是,一旦INPUT语句开始使用命名输入格式,SAS要求从此之后的变量值均使用这种方式读入数据,而不能使用其他的输入方式。如果后面的数据格式和命名输入格式不一致,程序就会出错。
例5.11 使用命名输入格式。
data a;
input date yymmdd10. fullshr stkcd=$ lstknm=$;
cards;
2001-01-18 1486553100 stkcd=600001 lstknm=邯郸钢铁
;
run;
以下程序中使用了命名输入格式,但后面的变量fullsh未用命名输入格式,因而读数据出错。
data a;
input date yymmdd10. stkcd=$ lstknm=$ fullsh;
cards;
2001-01-18stkcd=600001 lstknm=邯郸钢铁1486553100
;
run;
LOG窗口显示出错信息:
RULE:
date=14993 stkcd=600001 lstknm=邯郸钢铁 fullsh=. _ERROR_=1 _N_=1
NOTE: INPUT 语句到达一行的末尾,SAS 已转到新的一行。
NOTE: 数据集 WORK.A 有 0 个观测和 4 个变量。
命名方式输入的数据可以不考虑变量的排列顺序。
data a;
input date yymmdd10. fullshr stkcd=$ lstknm=$;
cards;
2001-01-18 1486553100 lstknm=邯郸钢铁 stkcd=600001
;
run;
例5.12
data list2;
informat header $30. name $15.;
input header= name=;
datalines;
header=
;
run;