在线试读

get_product_contenthtml SAS技术内幕:从程序员到数据科学家
系统会生成如下数据集(见图2-8),存放在 C:\temp 目录中。与利用临时库 Work 不同,
该数据集在你SAS 会话结束后依然存在,存放在 C:\temp\class.sas7bdat 文件中。
图2-8 由数据生成的 MYLIB.CLASS 数据集内容
磁盘上的数据文件名称依赖于操作系统的文件系统,如 Windows 平台的FAT/FAT32
和NTFS 文件系统,不区分大小写。而Linux/Unix 平台则区分大小写,SAS 则一律使用
小写字母生成数据集文件名。如果我们要读取Unix/Linux 平台上包含大写字母的文件名,
需要在SAS 会话中启用系统选项VALIDMEMNAME=EXTEND 并且数据集的名称必须
与磁盘上的文件名大小写完全匹配才能正常读取。
(2)如果数据行包含特定的分隔符,我们可以利用INFILE 语句来指向系统特殊的
文件引用DATALINES ,并且使用语句参数DELIMITER='< 分隔符>' 来指定分隔符。
指定分隔符时也可以使用十六进制方式,如DELIMITER='2C 'X; 它与下面的代码使用
逗号分隔符等价(见程序 2-17),代码输出结果与程序 2-16 相同。
程序2-17 指定分割符
data myclass;
infile datalines delimiter=',';
input Name $ Sex $ Age Height Weight;
datalines;
Alfred,M,14,112.5,69
Alice,F,13,84,56.5
Barbara,F,13,98,65.3
run;
(3)如果数据行本身包含SAS 语句的结束标志符分号“;”的话,则我们必须使用
DATALINES4 语句来标记后续数据行,该语句表示后续数据行是用4 个连续的分号来标
记数据行结束的。DATALINES4 也可以使用该语句的别名为 LINES4 或CARDS4 表示。
程序 2-18 中字符型变量 NAME 的值包含分号,则我们必须以DATALINES4 来输入数据。
程序2-18 数据包含分号
data myclass;
input Name $ Sex $ Age Height Weight;
datalines4;
Alfred; M 14 112.5 69
Alice; F 13 84 56.5
Barbara; F 13 98 65.3
;;;;
数据包含引号并且引号中的数据包含字段分隔符本身时,我们需要在INFILE 语
句上启用分隔符敏感数据选项DSD(DELIMITOR-SENSITIVE DATA,DSD)。此时

如果数据行中甚至还包含SAS语句结束符分号,则我们同时需要使用DATALINES4
而非DATALINES语句进行标记。下面的代码详细展示了此时如何正确读取数据(见
程序 2-19)。

程序2-19 数据包含分隔符和引号

data myclass;

 infile datalines4 dsd; /* DSD 使用逗号分隔,且引号文本中包括逗号*/

 input Name:$9. Sex $ Age Height Weight Address:$32. Description $24.;

 datalines4;

Alfred,M,14,112.5,69, "Alfred's home Beijing, China", Alfred's

description;

Alice,F,13,84,56.5, "Alice's home, Beijing, China", Alice's

description;

Barbara,F,13,98,65.3, "Babara's adress, Beijing, China", Barbara's
description;

;;;;

读取后的数据中可包括空格、逗号与分号(见图2-9)。



图2-9 读取数据中包含空格和分号

(4)如果数据行本身变长,也就是说数据行参差不齐,其中字符型变量又包含空
格字符。此时我们需要使用 SAS 提供的列指针来明确指定每一个数据行中变量读取的起
止位置,从而正确地截取变长的字符串。如下代码对字符型 NAME 变量明确指示从数
据行前 15 个字节中读取值,而对字符型 SEX 变量则没有指定列指针,默认读取前一
个变量之后到下一个变量之前之间的字符。这种方式一般用于表单化的数据读取(见
程序 2-20),生成的结果如图2-10 所示。

程序2-20 变长数据-按位置读取

data myclass;

 input Name $1-15Sex $ Age Height Weight;

 datalines;

Alfred Liu M 14 112.5 69

Alice Wang F 13 84 56.5

Barbara Deng F 13 98 65.3

;



图2-10 读取变长数据

(5)如果在一个数据行包括多个观测,数据呈锯齿状。我们该如何读取呢?SAS



SAS技术内幕:从程序员到数据科学家
在INPUT 语句上设计了一个特殊选项@@,用于告诉SAS 从数据行完整读取一个观测
后不要马上读取下一个数据行,而是继续从当前的数据缓冲区中继续读取数据填充观测。
这种灵活设计为读取各种复杂格式的数据,节省 SAS 代码内嵌数据行数非常有用。比如
下面的代码依然可以读取数据行中的锯齿状数据(见程序 2-21)。
程序2-21 忽略原始数据格式从缓冲区连续读取
data myclass;
input Name $ Sex $ Age Height Weight @@;
datalines;
Alfred M 14 112.5 69
Alice F 13 84 56.5 Barbara F 13 98 65.3
;
(6)如果数据集的一个观测来自多行文本,此时需要联合游标控制符# 和@ 来读
取数据,它们分别表示对应数据行和列的偏移位置。此时,input 语句有若干参数可指定
用来接收执行过程中所读取的文件指针信息。下面的代码中数据行格式比较混乱,我们
需要一次读取3 行文本才能获得一个观测的完整数据(见程序 2-22)。
程序2-22 利用游标控制符读取跨行数据
data mydata;
infile datalines line=LN col=COL;
input name $ 1-10#2 @3 Sex $ /*从第2行第三列读取一个字符串变量 Sex */
#3 Age Weight Height; /*从第3行读取三个数值变量 */
datalines;
Alfred
M
14 112.5 69
Alice
F
13 84 56.5
Barbara
F
13 98 65.3
;