操纵数据是数据学家的重要工作内容之一,主要用来为数据分析或创建报表准备必要的内容。传统数据仓库领域的数据工作(ETL或ETCL)——数据的抽取(Extract)、转换(Transformation)、清洗(Clean)和加载(Load)都是数据科学家的家常便饭。
SAS 组织管理数据的最基本单位是SAS 逻辑库(SAS Library)和SAS 数据集(SAS Dataset)。细心的读者也许会记得SAS的HelloWorld 程序,第一行都是以 Data 语句开头?因为 SAS 语言就是面向数据分析的专门语言,在SAS的世界里数据是分析的基础,也是从数据到智能的基石。后面我们会逐渐领略到 “数据就是分析的基础” 这一精髓!
SAS 逻辑库是SAS为面向数据处理而设计的 引用和存储 单位,是SAS组织数据的顶级单位。一个SAS 逻辑库可以包含若干 成员(Member),其中最常用的成员为 SAS数据集(SAS Dataset)。SAS 逻辑库和 SAS数据集的概念可分别对应传统关系型数据库(RDBMS)的数据库和数据表的概念,但SAS 逻辑库包含更加丰富的数据内容和灵活的结构。
SAS 系统预定义了若干系统逻辑库,每次启动SAS运行环境(也称为建立一个SAS会话)的时候,这些逻辑库就已经自动建立,供用户使用。一般包含5个永久库(sasuser,sashelp和3个地图专用的逻辑库:maps、mapsgfk、mapssas)和一个临时库 work。
1.临时库(WORK):每次启动 SAS 运行环境的时候,SAS都会有一个临时逻辑库 work被建立。临时库 work 用于在SAS 会话期间临时存储和访问数据,SAS 会话结束(即退出SAS运行环境)后临时库work和其中的内容会被自动删除。
比如:在Windows 平台的SAS中,每次启动一个SAS会话,系统会在操作系统临时目录%TEMP%下的“SAS Temporary Files”目录中创建一个会话特定的临时路径(比如:C:\Users\sbjyiw\AppData\Local\Temp\SAS Temporary Files\ _TD8212_SBJYIW_),这是SAS 会话期间存放各种临时数据的磁盘路径。
2.永久库:永久库中的数据并不因SAS 会话结束而消失,也就是SAS运行结束后那些数据依然存在。SAS 会话的永久库由SAS启动过程中使用的那个配置文件 sasv9.cfg 来指定。
注意:SAS几乎支持所有的语言和编码,在SAS 安装环境中sasv9.cfg 配置文件有多个,默认提供英文版、支持DBCS的英文版,Unicode版、和十余种语言特定的版本,对应SAS 安装后的启动菜单。sasv9.cfg 也支持使用 -config 参数指向另一个配置文件sasv9.cfg 来重用其设置,从而构成配置文件体系。
sashelp:逻辑库 sashelp是系统预定义的只读逻辑库,提供系统初始化后可用的数据。逻辑库sashelp 在sasv9.cfg 中由以下配置被映射到多个目录,从中读取可用的数据集文件。
SASHELP (
"!SASCFG\SASCFG"
"!SASROOT\nls\zh\sashelp"
"!SASROOT\core\sashelp"
…
)
sasuser:逻辑库 sasuser是系统预定义的可写逻辑库,用来在SAS 会话运行期间存放当前用户特定的数据。一般用来隔离不同SAS用户数据。
逻辑库 sasuser 在sasv9.cfg 中使用 -SASUSER 指定,对应于操作系统中的用户主目录或者数据库中的特定用户数据库。比如在 Windows 系统中,-SASUSER 被指向 "?CSIDL_PERSONAL\My SAS Files\9.3",比如:C:\Users\sbjyiw\Documents\My SAS Files\9.3
3.用户库:也称用户自定义逻辑库,用户可以在 SAS程序中用libname 语句自定义若干用户库,用来引用存放于磁盘上或者其他数据库服务器上的数据。比如:
libname mylib 'c:\temp'; *定义我的逻辑库;
*在 mylib 中创建系统逻辑库 sashlep.class 的拷贝,实际上文件存于 c:\temp;
data mylib.foo;
set sashelp.class;
run;
*打印我的数据 mylib.foo,实际上引用 c:\temp\foo.sas7bdat;
proc print data=mylib.foo;
run;
不管SAS运行在什么操作系统上,你可以用同样的逻辑库引用名(Library reference name)来引用你的SAS 逻辑库,逻辑库引用名是当前SAS会话能够识别的逻辑名称,指向某个操作系统能够识别的物理位置或者数据访问引擎的访问入口。逻辑库引用在SAS代码中隔离了操作系统或数据库系统的物理位置,提高了代码的可移植性。
你也可以在任何需要的时候,改变某个逻辑库引用的物理指向或者清除已经分配的某个逻辑库引用。
*注意: 改变逻辑库 mylib 的指向为 c:\windows;
libname mylib "c:\windows";
*注意: 清除逻辑库 mylib, 此语句后 mylib 将不再可用;
* 但SAS并不删除c:\temp 目录中任何物理文件内容;
libname mylib clear;
在SAS代码里,如果你想要删除 c:\temp 目录中的物理文件 foo.sas7bdat,可以调用如下语句:
*删除数据集 mylib.foo,磁盘上的物理文件也相应删除;
proc datasets library=mylib;
delete foo;
run;
在 SAS 运行环境中,你可以用鼠标右键点击逻辑库来查看逻辑库的属性,如下。
你也可以使用 libname 语句的 LIST功能在日志窗口中显示逻辑库信息,你也可以使用关键字_ALL_ 来列出系统中所有可用的逻辑库的信息。
libname mylib LIST;
libname _ALL_ LIST;
输出如下:
SAS 数据集(Dataset)
SAS 数据集是一种SAS特定的结构化数据文件,这种表状数据由变量(列)和观测(行)组成。变量和观测对应传统数据库中表的列和行。
SAS数据集从结构上看包括 描述部分 和 数据部分。描述部分是数据的元数据,主要包括数据集的属性信息,比如数据集名称、文件编码、创建日期,观测数目(行数)、变量数目(列数)、以及每一个变量的具体属性定义(名称、类型、长度、标签、输入/输出格式)等。数据部分就是每一行记录本身。要查看数据集的元数据,可以使用 PROC CONTENTS 过程步来显示。
proc contents data=sashelp.class;
run;
在 SAS 代码中,数据集 [Libref.]dsname 两级名称进行引用,如果是临时库 WORK中的数据,则可以省略逻辑库引用名。
l SAS 数据集中的每一列,在SAS代码里称为变量,其名称由1-32字节长的字母、下划线和数字组成,但不能以数字开始。SAS内部用大写形式创建变量,故SAS代码中不区变量名称的大小写。
l SAS变量类型包括 字符型 和 数值型 ,缺省都是8字节长。字符类型的变量值可为1-32767个字节,数值型可为2-8任意字节长的整数或浮点数(Windows/Linux为3-8,IBM大型机为 2-8)。
注意:这儿谈论的SAS变量类型是传统意义上SAS数据集中的数据类型,在后面章节中我们将看到其实SAS代码能支持更加丰富的数据类型。然而,一旦持久化到SAS数据集后则只有定长字符型和数值型两大类数据类型。
l SAS变量的输出格式用于指定该变量(列) 的缺省输出格式。这样相同的SAS内部存储值可以根据不同的输出格式生成不同的字符串表达。SAS 变量的输入格式则用于告诉SAS按照该输入格式从外部数据源读取数据到SAS 数据集中。下面将重点讲一下SAS输入输出格式。
SAS 输入输出格式
SAS 输入/输出格式就是一个包含小数点 . 的特殊字符串,完整的格式包括格式前缀 $(字符型专用)、格式名称 formatname,输出宽度w,小数点位数 d(数值型专用)等信息。完整形式如下:
<$>formatname<w>.<d>
输入/输出格式是 字符串形式的语义表达 和 SAS内部存储 之间的桥梁。根据SAS数据类型的不同分为字符型格式和数值型格式两大类型,其中数值类型格式还包括用于数值,货币,日期/时间/日期时间等三个子类的格式。格式用于输入称为INFORMAT(输入格式),用于输出称为FORMAT(输入出格)。
字符型格式必须在格式名前面加美元符 $ (其实是源于英文字符串 String的首字母) 表示,w表示输出的总宽度。对于数值型变量,还可以指定小数点后的位数d。比如:
l 字符型格式:$w.
l 数值格式:w.d
1) COMMAw.d 表示用逗号, 做千位分隔符,小数点
2) COMMAXw.d 表示用小数点做千位分隔符,逗号作小数点,与COMMA相反,用于欧洲部分国家的数值显示。
l 货币:
1) DOLLARw.d 表示变量按美元格式输出:美元符号开头,逗号千位分隔符,小数点
2) EUROw.d 表示变量按欧元格式输出:欧元符号,逗号千位分隔符,小数点
3) EUROXw.d 与EURO相同,但以小数点做千位分隔符,逗号作小数点
运行如下代码,检查输出结果:
data _null_;
c="abcdefghijklmn"; *14bytes;
put "char=" c;
put "char=" c $;
put "char=" c $14.;
n=1234.567890;
put "w.d= " n 12.3;
put " COMMAw.d=" n COMMA12.3;
put "COMMAXw.d=" n COMMAX12.3;
put "DOLLARw.d=" n DOLLAR12.3;
put " EUROw.d=" n EURO12.3;
put " EUROXw.d=" n EUROX12.3;
run;
系统输出:
char=abcdefghijklmn
char=abcdefghijklmn
char=abcdefghijklmn
w.d= 1234.568
COMMAw.d= 1,234.568
COMMAXw.d= 1.234,568
DOLLARw.d= $1,234.568
EUROw.d= E1,234.568
EUROXw.d= E1.234,568
l 日期格式:
1) DATEw. 比如DATE7. 显示 16JAN17
2) MMDDYYw. 比如 MMDDYY10. 显示 01/01/1960
3) YEAR4. 显示 1960
4) NLDATE. 显示本地语言格式的日期,比如中文SAS上显示 2017年01月22日
l 时间:
1) TIMEw. 比如 TIME. 显示 22:16:27
2) NLTIME. 显示本地语言格式的时间,比如中文SAS上显示 17时18分30秒
l 日期时间:
1) DATETIME. 比如 DATETIME. 显示 16JAN17:22:14:35
2) NLDATM. 显示本地语言格式的日期时间,比如 2017年01月22日 17时18分30秒
data _null_;
mydate=today();
put mydate DATE. ;
put mydate MMDDYY.;
put mydate YEAR.;
mytime=TIME() ;
put mytime TIME.;
mydt=datetime();
put mydt DATETIME.;
put mydate NLDATE.;
put mytime NLTIME.;
put mydt NLDATM.;
run;
系统输出:
22JAN17
01/22/17
2017
17:18:31
22JAN17:17:18:31
2017年01月22日
17时18分30秒
2017年01月22日 17时18分30秒
结语:SAS 数据集是SAS 组织数据的容器,更上一级采用SAS 逻辑库进行组织。SAS 数据集包含描述数据的元数据部分(表的属性以及行列定义),以及真正包含数据的观测(数据行)组成。不管数据是存在磁盘上,还是在外部数据库或应用系统中,在SAS 内部都统一通过逻辑库引用 进行访问,用户无须关注数据的存储细节,而是关注数据在分析层次的表达。
SAS 数据集中的观测(表记录)一般有三种生成方式: 1) DATA 步通过内嵌数据行、基于已有的数据集、或者外部数据库/系统来生成。2)SAS数据集通过 PROC IMPORT 或者其他 面向数据操作的PROC (如 PROC SQL)生成;3)通过面向分析的PROC自动生成,一般为间数据或分析结果数据。下面我们以生成一个最简单的数据集作为本章结束,理解SAS数据集的结构。
libname mylib 'c:\temp';
data mylib.mydata (label="This is my first data");
length column1 $32;
column1="The only constant is change";
column2=1234.5678;
format column2 dollar10.2;
label column1="This is Char column";
label column2="This is Num column";
run;
proc contents; run;
proc print; run;