SAS读取数据的一些方法


第二章 数据读取

2.1 SAS读取的对象(DBMS、PC File、Flat File、Instream Data)

2.2 SAS与数据交互方式(libname、sql、import\export、infile:input、IO函数、dde、saspipe)

2.3 数据的导入

2.3.1利用LIBNAME语句导入数据

2.3.2利用SQL导入数据

2.3.3 IMPORT导入数据

2.3.4 infile导入数据

2.3.5 INPUT 语句

2.3.6 DDE 方法

2.3.7 sas pipe

2.3.8 IO 函数

2.3.9 Import Wizard 使用导入向导

 

 

 

 

 

 

 

 

 

2.1 SAS读取对象

在做数据分析前需要获取数据,成功导入外部数据是SAS分析的第一步,也是最基础且重要的一步。SAS 作为老牌的统计软件发展至今,已经集成了丰富的数据获取与管理功能组件。本章我们就SAS如何获取数据做重点介绍。

SAS可读取任意格式、任意类型的原始数据,包括变长记录、二进制文件、无格式的数据,甚至是包含混乱或缺失数据的文件。

SAS可直接访问某些厂商的文件,如:BMDP、SPSS 和 OSIRIS 文件。对于其他格式的文件,可以使用 SAS/ACCESS,它可以如同访问 SAS 内部数据一样访问外部数据。例如,可以读取存储在 Microsoft Excel 电子表格、Microsoft Access 表、dBASE 文件、ORACLE 或其他 DBMS 中的数据

SAS/ACCESS 提供对以下类型数据的访问:

2-1

说到数据读取这个问题,我们可以从 SAS 读取的对象来说 , 当然也可以从读取的方式来说。从 SAS 读取的对象来说,我们可以把外部数据文件归为四类。

(1)数据库管理系统(DataBase Management System, DBMS)数据文件,市面的DBMS 非常之多,常见的如 DB2、 Sybase、 mySQL、 MS SQL Server、 Oracle、 Teradata 以及 Hadoop 等。

(2)单机文件(PC File),单机文件应是相对 DBMS 数据文件而言的,常见的单机数据文件包括MS Access、 MS Excel、 Lotus、 DBF 以及大家更熟悉的 JMP、 SPSS、Stata、 Paradox 等软件的数据文件。

(3)平面文件(Flat File),是一种包含没有相对关系结构的记录的文件,一个 Flat File 既可以是纯文本文件 (Plain Text File),也可以是二进制文件 (Binary File),对于我们而言,最常见的是纯文本 TXT 文件和 CSV 文件。

(4)流式数据(Instream Data),即 SAS 程序中 DATA步里 DATALINES(CARDS)语句后的数据行。

 

 

 

2.2 SAS与数据交互方式

从 SAS 读取的方式有很多种,具体需要结合实际采取适当的方式。(更准确地讲,应该是 SAS 和外部数据交互的方式,因为不仅仅读入,还有导出等其他交互操作)

(1) LIBNAME 语句, LINAME 语句其实是动用了我们前面提到的数据库引擎来实现 SAS 与其他数据库文件的互通,这是 SAS 获取外部数据库文件最为快速、直接的方式。

(2) SQL 直通设施(SQL Pass-Through Facility),这是直接在 SAS 会话中使用其原生 SQL 语法的方式。

(3) IMPORT 过程,前面的两种方式都是包含在 SAS/ACCESS 模块中的, IMPORT过程则是Base SAS与外部数据集沟通的方式,当然我们在利用IMPORT/EXPORT 过程时,如果安装且拥有 SAS/ACCESS 模块的权限,能够支持的数据类型会更丰富。

(4) INFILE INPUT 语句,这是通过 DATA 步编程的方式读取外部数据或者流式数据。

(5) INPUT DATALINES 语句,这是通过 DATA 步编程的方式读取流式数据。

(6) DDE 动态数据交换

(7) sas pipe 信息传输管道

(8) IO 函数,通过输入输出函数打开数据文件,这是一种比较少见的方式

(9)Import Wizard 使用导入向导

在实际工作中,我们的思维模式通常是碰到一种数据,然后思考采用何种方式读入。因此,这里引用某位笔者将数据类型和读入方式做一个综合总结。从需求出发找解决方法,即从数据类型出发,总结可用的读入方式,并推荐合适的读入方式。具体见表 2-2 的总结

 

 

 

2-2

 

 

2.3数据的导入

在SAS系统中可以通过数据步编程以及界面操作实现数据的输入输出,这里介绍一些常用的通过数据步导入数据的方式。

 

2.3.1 利用LIBNAME语句导入数据

 

LIBNAME是与SAS库关联的库引用(libref)的名称。LIBNAME语句定义SAS逻辑库。

 

语法

LIBNAME 逻辑库名<选择引擎> '(有效的Windows路径名或设置为有效Windows路径名的环境变量 )' 
<指定为此库使用扩展服务器内存>, <指定SAS等待锁定文件可供另一个进程使用的秒数。>;

LIBNAME 逻辑库名_ALL_ LIST; (在Log窗口列出逻辑库的属性)

LIBNAME 逻辑库名_ALL_ CLEAR;(清除所有与库标记的联系)

LIBNAME声明概述

LIBNAME语句将libref与永久SAS库相关联。 它还可用于列出SAS库的文件属性。 LIBNAME语句还用于清除libref

需要注意的是单词AUXCONNULPRNLPT1-LPT9COM1-COM9Windows下的保留字。 不要将它们用作librefs

使用LIST选项,您可以使用LIBNAME语句列出SAS库的属性。 以下为LIBNAME语句导致数据库属性列表:

 

 

示例 1:指定引用 SAS 文件的逻辑库引用名

假定您希望定义一个 SAS 逻辑库,该库引用 Windows 操作环境中某个包含 SAS 数据集的文件夹。然后,您希望创建并打印新的数据集。下面的程序将定义 Sales 逻辑库,并引用该逻辑库中的 SAS 文件。

 

提示: 可以复制这些程序,然后在 SAS 中提交。不过,需要编辑 LIBNAME语句中的目录,才能引用操作环境中的现有目录。

/*************************************/

/* 定义逻辑库 */

/*************************************/

libname sales 'C:\Users\Xx\Desktop';

/*************************************/

/* 从原始数据创建新数据集 */

/*************************************/

data sales.quarter1;

length Department $ 7 Site $ 8;

input Department Site Quarter Sales;

datalines;

Parts Sydney 1 4043.97

Parts Atlanta 1 6225.26

Parts Paris 1 3543.97

Repairs Sydney 1 5592.82

Repairs Atlanta 1 9210.21

Repairs Paris 1 8591.98

Tools Sydney 1 1775.74

Tools Atlanta 1 2424.19

Tools Paris 1 5914.25

run;

/*************************************/

/*打印新数据集 */

/*************************************/

proc print data=sales.quarter1;

run;

 

 

例 2:指定引用 DBMS 数据的逻辑库引用名

现在假定您希望打印 Oracle 表和 DB2 表。下面的程序将说明,如何指定带有相应的 SAS/ACCESS 引擎和选项的 LIBNAME 语句。您为 DBMS 指定逻辑库引用名之后,可以使用标准的 SAS 两级名称将其中的表和视图作为 SAS 数据集引用。

 

由于可以在 SAS 程序中定义任意多的逻辑库引用名,所以您可以在同一个 SAS 程序中处理源自多个 DBMS 的数据。

Libname xx 'D:\mydb';

Libname xxx 'D:\mydb'; (两个库标识对应一个物理地址)

Libname xxxx ('D:\mydb1' 'D:\mydb2'); (多个物理地址指定一个逻辑库))

 

 

 

/*************************************/

/* 以Oracle为引擎建立逻辑库 */

/*************************************/

libname myorlib oracle user=scott password=tiger

path="blunzer:v7" schema=hrdept;

/*************************************/

/* 以DB2为引擎建立逻辑库 */

/*************************************/

libname mydblib db2

noprompt="user=testuser;

password=testpass;database=testdb";

/*************************************/

/* 打印 Oracle 表 */

/*************************************/

proc print data=myorlib.all_employees;

where state='CA';

run;

 

/*************************************/

/* 打印 DB2 表 */

/*************************************/

proc print data=mydblib.customers;

where state='CA';

run;

 

/*************************************/

/*取消关联一个或多个当前分配的libref。 */

/*************************************/

libname myorlib clear;

libname mydblib clear;

 

 

假定您希望在远程主机上执行某些处理,然后下载 SAS 结果数据集,在本地主机上创建永久数据集,最后在本地主机上打印报表。下例将说明如何将上述所有任务编入一个程序。

 

 

 

/*************************************/

/*准备登录 */

/*************************************/

options comamid=netbios remote=netpc;

libname lhost 'c:\sales\reg1';

/*************************************/

/* 登录并下载数据集 */

/*************************************/

signon;

rsubmit;

libname rhost 'd:\dept12';

proc sort data=rhost.master

out=rhost.sales;

where gross > 5000;

by lastname dept;

run;

proc download data=rhost.sales

out=lhost.sales;

run;

endrsubmit;

/*************************************/

/* 在本地会话中打印数据集 */

/*************************************/

proc print data=lhost.sales;

run;

 

 

2.3.2利用SQL(SQL Pass-Through Facility)导入数据

SQL传递工具使用SAS / ACCESS连接到DBMS并将语句直接发送到DBMS以供执行。 作为SAS / ACCESS LIBNAME语句的替代方法,此工具允许您使用DBMS的SQL语法。 它支持DBMS支持的任何非ANSI标准的SQL。

但是,并非所有SAS / ACCESS接口都支持此功能。 要确定您的环境是否可用,请参阅主机的SAS / ACCESS功能。

以下是您可以使用SQL传递工具完成的任务:

· 使用CONNECT和DISCONNECT语句建立和终止与DBMS的连接。

· 使用其EXECUTE语句将动态非查询,特定于DBMS的SQL语句发送到DBMS。

· 使用PROC SQL SELECT语句的FROM子句中的CONNECTION TO组件直接从DBMS检索数据。

您可以在PROC SQL查询中使用SQL传递工具语句,也可以将它们存储在SQL视图中。 创建SQL视图时,您在CONNECT语句中指定的任何参数都将与视图一起存储。 因此,在SAS程序中使用视图时,SAS可以建立与DBMS的适当连接。

有关SQL传递工具的DBMS特定详细信息,请参阅SAS帮助文档中SAS / ACCESS接口的参考部分。

语法

PROC SQL <option(s)>;

CONNECT TO dbms-name alias> 
<(<database-connection-arguments> <connect-statement-arguments> )>;

DISCONNECT FROM dbms-name | alias;

EXECUTE (dbms-specific-SQL-statement) BY dbms-name | alias;

SELECT column-list FROM CONNECTION TO dbms-name | alias (dbms-query)

示例1:导入Excel文件

 

示例2SAS访问数据库

这里说的访问数据库不是把数据库作为一个lib 来访问,而是通过connection 来访问,为什么要用sas/access 的这种办法来访问DBMS呢,是因为要处理大量数据的时候,SAS 要在本机生成一些文件(临时文件之类),而把sql 语句直接提交给DBMS,由DMBS 执行,SAS 就不会需要中间这些步骤了。

简单来说,就是把sql 语句交给DBMS engine 来执行,这种方式在SAS 里叫做

Pass-Through Facility。

下面是一个完整的pass-through 方式执行sql 的语句:

proc sql;

connect to oracle as mydb (Path='ConnectionString' user='dbuser'

password='passwd');

%put &sqlxmsg;

select count(*) from connection to mydb

select count(*) from connection to mydb

(select * from scott);

%put &sqlxmsg;

disconnect from mydb;

quit;

1. connect to 语句是连接到数据库,然后给sas 一个别名,叫mydb

2. select count(*) from connection to mydb 这里是指从DBMS 返回的结果从select 数据,而真正运行在dbms 端的语句则是括号中的这句(select * from suspect_duplicates_2);

3. 断开连接: disconnect from mydb;

 

%put &sqlxmsg; 是sas 的宏,用来输出dbms 的错误信息

以上的示例是用来select 有结果集的,对于没有结果集的sql 语句,要用到EXECUTE,见下例:

proc sql;

connect to oracle as mydb (Path='ConnectionString' user='dbuser'

password='passwd');

%put &sqlxmsg;

execute

(create table .......) by mydb;

%put &sqlxmsg;

disconnect from mydb;

quit;

括号里的sql 语句可以是create, update, 等等...

 

 

PASSTHTOUGH方式通过CONNECT语句建立SAS和其他数据库之间的通信,并使用SQL过程将其他数据库数据直接导入到SAS系统

在此示例中,SAS / ACCESS使用dbcon别名连接到Teradata DBMS。

proc sql;

connect to teradata as dbcon (user=testuser pass=testpass);

quit;

 

示例使用别名DBCON连接oracle(连接别名是可选的):

proc sql;

connect to oracle as bieming

(user=yonghuming password=mima

path=lujing);

quit;

 

要退出SQL传递工具,请使用工具DISCONNECT语句,然后退出PROC SQL语句。 此示例使用别名DBCON1断开用户与DB2数据库的连接,并终止SQL过程。

proc sql;

connect to db2 as dbcon1 (ssid=db2a);

…more SAS statements…

disconnect from dbcon1;

quit;

 

此示例将Oracle SQL查询(下面突出显示)发送到Oracle数据库进行处理。 Oracle SQL查询的结果充当PROC SQL FROM子句的虚拟表。 在此示例中,MYCON是连接别名。

proc sql;

connect to oracle as mycon (user=myusr1

   password=mypwd1 path='mysrv1');

%put &sqlxmsg;

select *

   from connection to mycon


					(select empid, lastname, firstname,
				


					hiredate, salary
				


					 from employees where 
				


					hiredate>='31-DEC-88');

%put &sqlxmsg;

disconnect from mycon;

quit;

 

CONNECTION TO组件指定要使用或要创建的DBMS连接(如果已省略CONNECT语句)。 然后,CONNECTION TO使您可以直接通过PROC SQL查询检索DBMS数据。

您在PROC SQL SELECT语句的FROM子句中使用CONNECTION TO组件:

PROC SQL;

SELECT column-list

FROM CONNECTION TO dbms-name (dbms-query)other optional PROC SQL clauses

QUIT;

此示例为查询提供名称并将其存储为SQL视图样本。

libname samples 'SAS-library';

proc sql;

connect to oracle as mycon (user=myusr1

   password=mypwd1 path='mysrv1');

%put &sqlxmsg;

create view samples.hires88 as

   select *

      from connection to mycon


					(select empid, lastname, firstname,
				


					hiredate, salary
				


					from employees where
				


					hiredate>='31-DEC-88');

%put &sqlxmsg;

disconnect from mycon;

quit;

 

2.3.3 IMPORT导入数据

IMPORT程序有什么作用?

 

IMPORT过程从外部数据源读取数据并将其写入SAS数据集。 在Base SAS 9.4中,您可以导入JMP文件和分隔文件。

在分隔文件中,分隔符(例如空格,逗号或制表符)分隔数据值列。 如果您将SAS / ACCESS接口许可给PC文件,则其他外部数据源可以包括Microsoft Access数据库文件,Microsoft Excel文件和Lotus电子表格。

运行IMPORT过程时,它会读取输入文件并将数据写入指定的SAS数据集。 默认情况下,IMPORT过程期望变量名称出现在第一行中。 该过程扫描前20行以计算变量,并尝试确定每个变量的正确信息和格式。 您可以使用IMPORT过程的语句执行以下操作:

· 指示SAS扫描变量以确定类型和长度的行数(GUESSINGROWS =)

· 指示SAS开始读取数据的行(DATAROW =)

· 修改SAS是否提取变量名称(GETNAMES =)

默认情况下,IMPORT过程将分隔文件读取为不同的记录长度文件。 如果外部文件具有固定长度格式,请使用带有INFILE语句的SAS DATA步骤,该语句包含RECFM = 和LRECL =选项。

 

语法:

PROC IMPORT

DATAFILE ="filename"|TABLE ="表名"

OUT = SAS数据集<(SAS数据集选项)>

;

 

从分隔文件导入的语句

Datarow= N;

DELIMITER = char |'nn'x;

GETNAMES = YES | NO;

GUESSINGROWS = n |MAX;

 

PROC IMPORT将外部数据文件导入SAS数据集

DATAROW开始从分隔文本文件中的特定行读取数据

DELIMITER指定用于分隔输入文件中数据列的分隔符

GETNAMES从输入文件第一行的数据值生成SAS变量名

GUESSINGROWS指定要扫描的输入文件的行数,以确定变量的相应数据类型和长度

 

可选参数摘要

DBMS=标识符

指定要导入的数据类型。

Replace

覆盖现有的SAS数据集。

SAS data set options

指定SAS数据集选项。

 

DATAFILE="filename" | "fileref"

指定输入PC文件,电子表格或分隔外部文件的完整路径和文件名或fileref。 fileref是与输出文件的物理位置相关联的SAS名称。 要分配fileref,请使用FILENAME语句

仅当SAS支持数据类型时,IMPORT过程才能导入数据。 SAS支持数字和字符类型的数据,但不支持(例如)二进制对象。 如果要导入的数据是SAS不支持的类型,则IMPORT过程可能无法正确导入。 在许多情况下,该过程尝试将数据转换为其最优。 但是,某些类型无法进行转换。

默认情况下,IMPORT过程将分隔文件读取为不同的记录长度文件。 如果外部文件具有固定长度格式,请使用带有INFILE语句的SAS DATA步骤,该语句包含RECFM = F和LRECL =选项。

对于分隔文件,扫描前20行以确定变量属性。 您可以使用GUESSINGROWS =语句增加扫描的行数。 所有值都以字符串形式读入。 如果可以将日期和时间格式或数字信息应用于数据值,则将类型声明为数字。 否则,类型仍然是字符。

TABLE="tablename"

指定输入DBMS表的名称。 如果名称不包含特殊字符(如问号),小写字符或空格,则可以省略引号。 请注意,DBMS表名称可能区分大小写。

您必须拥有用于PC文件的SAS / ACCESS接口的许可才能导入到DBMS表。

导入DBMS表时,必须指定DBMS =选项。

 

REPLACE

覆盖现有的SAS数据集。 如果省略REPLACE,则IMPORT过程不会覆盖现有数据集。

 

DATAROW声明

开始从分隔文本文件中的指定行号读取数据。

默认值:当GETNAMES = NO:1时,GETNAMES = YES:2

当GETNAMES = NO时,DATAROW必须等于或大于1当GETNAMES = YES时,DATAROW必须等于或大于2。

DATAROW语句仅对分隔文件有效。

语法:datarow = n;

指定输入文件中的行号,以便IMPORT过程开始读取数据。

 

DELIMITER 声明

指定用于分隔输入文件中的数据列的分隔符。默认为空格

如果指定DBMS = DLM,则还必须指定DELIMITER =语句。

语法:DELIMITER=char?| 'nn'x;

指定用于分隔输入文件中的数据列的分隔符。 您可以将分隔符指定为单个字符或十六进制值。 例如,如果数据列由&符号分隔,请指定DELIMITER ='&'。

 

如果省略DELIMITER =,则IMPORT过程假定分隔符是空格。

 

GETNAMES声明

指定IMPORT过程是否根据输入文件第一行中的数据值生成SAS变量名称。默认是YES

仅对IMPORT过程有效。

如果使用VALIDVARNAME = ANY,则GETNAMES =可能不会将下划线作为数据值的前缀。

GETNAMES语句仅对分隔文件有效。

语法:GETNAMES=YES?| NO;

YES指定IMPORT过程从导入的分隔文件的第一行中的数据值生成SAS变量名称。

NO指定IMPORT过程生成SAS变量名称为VAR1,VAR2等。

注意:如果读取输入文件第一行中的数据值并且它包含在SAS名称中无效的特殊字符(例如空白),则SAS会将该字符转换为下划线。 例如,变量名称占用代码将成为SAS变量名称Occupancy_Code。 由于SAS变量名称不能以数字开头,因此GETNAMES =将下划线作为变量名称的前缀,而不是替换值的第一个字符。 例如,2014.CHANGES变为_2014_CHANGES。

 

GUESSINGROWS声明

指定要扫描的文件的行数,以确定变量的相应数据类型和长度。

默认值:20

该值应大于为DATAROW指定的值。

GUESSINGROWS语句仅对分隔文件有效。

语法:GUESSINGROWS=n | MAX;

表示IMPORT过程在输入文件中扫描的行数,以确定适当的数据类型和变量长度。 范围是1到2147483647(或MAX)。 扫描数据进程从第1行扫描到GUESSINGROWS选项指定的数字。

注意:您可以更改SAS注册表中的默认行值。 从SAS命令行输入regedit。 注册表编辑器打开后,选择Productsthen selectBASE然后selectEFIthen selectGuessingRows。

MAX

可以指定而不是2147483647。指定最大值可能会对性能产生负面影响。

 

示例1:

此示例导入以下分隔的外部文件,并创建名为WORK.MYDATA的临时SAS数据集:

 

Region&State&Month&Expenses&Revenue

Southern&GA&JAN2001&2000&8000

Southern&GA&FEB2001&1200&6000

Southern&FL&FEB2001&8500&11000

Northern&NY&FEB2001&3000&4000

Northern&NY&MAR2001&6000&5000

Southern&FL&MAR2001&9800&13500

Northern&MA&MAR2001&1500&1000

; 

程序说明
					

设置系统选项NODATE选项禁止在输出中显示日期和时间。 LINESIZE =选项指定输出行长度,PAGESIZE =选项指定输出页面上的行数。
					

options nodate ps = 60 ls = 80;

指定输入文件。指定输入文件是分隔文件。
					替换数据集(如果存在)。
					识别输出SAS数据集。
					

proc import datafile ="C:\Users\xujia\Desktop\delimiter.txt"

            DBMS= DLM

            OUT = MYDATA

             Replace;

将分隔符指定为&(&符号)。
					

     delimiter= '';

从第一行数据生成变量名称。
					

     getnames=yes;

Run;

打印出输出数据集。
					

proc print data = mydata;

Run;

 

示例2:使用Fileref导入特定的分隔文件
					

此示例导入以下以空格分隔的文件,并创建名为Work.States的临时SAS数据集。
					

Region State Capital Bird

South Georgia Atlanta 'Brown Thrasher'

South 'North Carolina' Raleigh Cardinal

North Connecticut Hartford Robin

West Washington Olympia 'American Goldfinch'

Midwest Illinois Springfield Cardinal


			

 

示例3:导入制表符分隔文件
					

此示例导入以下制表符分隔文件,并创建名为Work.Class的临时SAS数据集。
					

 


				
			

由于DATAROW =选项规范,第一行读取将是第5行。

Datarow行= 5;

指定分隔符。在ASCII平台上,选项卡的十六进制表示为'09'x。 在EBCDIC平台上,选项卡的十六进制表示为'05'x。

     delimiter='09'x;

run;

 


				
			

 

示例4:使用CSV扩展名导入逗号分隔文件

此示例导入以下以逗号分隔的文件,并创建名为Work.Shoes的临时SAS数据集。

指定输入数据文件。如果存在,则放置数据集。 指定输出数据集。

将GETNAMES =选项设置为"no"会导致不使用记录1中的变量名称。


			

此外还可以对Excel 以及access数据进行导入:

1 对Excel数据进行导入

PROC IMPORT OUT= WORK.C 
            DATAFILE= "D:\lol.xls" 
            DBMS=EXCEL REPLACE;
     SHEET="Sheet1$"; 
     GETNAMES=YES;
     MIXED=NO;
     SCANTEXT=YES;
     USEDATE=YES;
RUN;

MIXED=YES | NO;

将数字数据值转换为包含混合数据类型的列的字符数据值。 此选项仅在从Excel导入数据时有效。 默认值为NO,这意味着数字数据将作为缺失值导入到字符列中。 如果MIXED = YES,则引擎将为该列分配SAS字符类型,并将所有数值数据值转换为字符数据值。 此选项仅在将数据读取(导入)到SAS时有效。

SCANTEXT=YES;
会自动扫描,以最大的宽度作为改列字符变量的宽度。如果SCANTEXT=NO,则在不设定TEXTSIZE的情况下,默认长度为255。

USEDATE=YES;
使用日期变量。USEDATE=NO时,默认输入的将是日期时间变量,时间为该日的0点0分0秒。

 

对access数据进行导入

PROC IMPORT OUT =ACE

TABLE='ZED'

DBMS=ACCESS REPLACE;

DATABASE='C:\Users\xujia\Desktop\LOL.mdb'

UID='ADAM';

PWD='DEMAXIYA';

RUN;

 

2.3.4 INFILE导入数据

INFILE指定要使用INPUT语句读取的外部文件。

语法

INFILE file-specification <device-type> <options> <operating-environment-options>;

INFILE DBMS-specifications;

示例:

data lol;

Infile'c:\zed.dat'dlm = ',';

Input name $ age;

run;

若要创建永久数据及,需要指定二级数据集名称。例如:

libname mylol 'd:\hero';

data mylol.honor;

Infile 'c:\zed.dat'dlm =',';

Input name $ age;

Run;

 

例1:

读取路径c:\myrawdata\下的数据文件toadjump.dat

代码:

运行结果:

注:(1)Nosiy 的数据溢出到第二行了,但并不影响,SAS会按照变量顺序自动跳到下一行读取;

  1. 程序将不加选择的朱行朱列的读入所有数据记录。

Infile 还可以加上可选参数,

MISSOVER 选项(处理每行数据个数长短不一)

Input语句中输入几个变量,SAS在观测值中就读取几个变量,如果一行未读完,则进入下一行直到输入的变量都读取了变量值。可以让SAS不进入下一行读取,未赋值的变量设为缺失值。

例2:

读入下面数据 c:\myrawdata\allscores.dat 一个学生应该有5门课成绩,但由于最后两门是自学课程,不是所有学生都完成,故而缺失。此时需要加上MISSOVER。

代码:

运行结果:

DLM和DSD选项

默认读入的数据是空格分隔,若是其它分隔符分隔,在infile语句中机上DLM='分隔符':

逗号分隔--DLM=','

制表符分隔--DLM='09'X (制表符的十六进制是09)

有时后面需要再加上DSD,有三个作用:

  1. 忽略引号中数据的"假分隔符"
  2. 自动将字符串中的引号去掉;
  3. 将两个相邻的分隔符当做缺失值来处理。

     

    例3 :

    读取路径 c:\myrawdata\ 下的数据文件bands.csv,内容如下:

    注意第三行引号中的逗号并不是分隔符,另外,每行数据长短不一样,

    所以还需要机上MISSOVER。

    代码:

    运行结果:

    FIRSTOBS= M OBS=N 选项

    有的数据文件包括数据的描述,需要用该选项告诉SAS从第m行开始读取到第n行结束。

    例4 读取如下的数据文件 c:\myrawdata\icegreamsales2.dat :

    注意第3行到第5行是有效数据。

    代码:

    运行结果:

    读取固定列排列的数据

  4. 同一变量的值都占据相同范围的列内;
  5. 变量值是字符串或者标准数值。

    注:标准数据是指数据、小数点、正负号、和科学计算法的 E。逗号数据和日期都不是标准数值。比第一种的优势在于:

    · 不要求变量值之间有空格;

    · 缺失值可以直接用空格代替;

    · 字符串中可以包含空格;

    · 可以以跳过不需要的变量。

    语法

    Input 变量1 n-m;

    注:"n-m"表示变量1数据所占的列范围,第n列至第m列。

    示例:

    Input name $ 1-10 age 11-13 height 14-18;

    标准按固定排列的数据

     

    例5:

    读取路径 c:\myrawdata\ 下的数据文件 onionring.dat,内容如下:

    代码:

    运行结果:

     

    TRUNCOVER 选项

    使用固定列的input 或控制格式(下节)的input输入时,若某行的数据(+空格)没有占到指定列的宽度,可能会转到下一行读取,此时必须用TRUNCOVER选项,以避免这种错误发生。

    例6:

    读取如下数据(c:\myrawdata\address.dat)

    注意三行的长度都不一样,input中只能指定最长的一行。

    代码:

    运行结果:

    读取非标准格式的数据文件

    非标准格式的数据,包括日期数据、"8,796,432"、美元符号$、十六进制数等。

    语法:

    Input 变量名 变量格式,,;

    示例:

    Input name $ 10. age 3. height 5.1 birthdate mmddyy10. ;

    例7:

    读取路径 c:\myrawdata\ 下的数据文件 pumpkin.dat, 内容如下:

    代码:

    运行结果:

    程序说明:

  6. "Name $ 10."表示字符型变量Name,共占10列宽度,无小数位;
  7. "Heright 5.1"表示数值型变量Height,共占5列宽度,其中1位小数位;
  8. "+1"表示跳过一列,即原始数据中Age后面有一个空格;
  9. "MMDDYY10."共占10位的日期格式;
  10. Score1 -Score5 五个变量格式相同,可以用小括号共同指定格式;

     

    通常可以混合使用前面的三种方式,例如

    例8 读取路径 c:\myrawdata\ 下的数据文件 natpark.dat ,内容如下:

    代码:

    运行结果:

    程序说明:

    符号"@"是列指示器,"@40"告诉SAS在读取Acerage变量之前,移动到第40列去;若没有"@40",Comma9 告诉SAS读取9列,将会读取包括空格在内的9列,这便会导致输出结果有问题:

     

    2.3.5 INPUT 语句

    直接输入

    注:单个@ 使sas停留在下一个input语句不换行

    两个@ 使sas停留在下一次data步也不换行

     

    使用INFILE语句引用包含数据的数据文件后,需要指定有关数据排列方式的以下信息:

    · 变量的数量及其名称

    · 每个变量的类型,数字或字符

    · 每个变量值的格式

    · 与每个变量对应的列

    换句话说,您必须指定如何读取数据。

    INPUT语句描述输入记录中值的排列。 INPUT语句从先前执行的INFILE语句中指定的文件中读取记录,将值读入SAS / IML变量。

    有两种方法可以在SAS / IML INPUT语句中描述记录的值:

    列表(或扫描)输入

    格式化输入

    以下是类数据文件的有效INPUT语句的几个示例,当然,这取决于数据的存储方式

    如果数据在字段之间以空格或逗号存储,则可以使用列表输入。 例如,类数据文件的INPUT语句可能如下所示:

    Infile inclass;

    Input name $ sex $ age height weight;

    这些语句指定以下内容:

    · 有五个变量:NAME,SEX,AGE,HEIGHT和WEIGHT

    · 数据字段以逗号或空格分隔。

    · NAME和SEX是字符变量,用美元符号($)所示。

    · AGE,HEIGHT和WEIGHT是数值变量,所以不用。

    数据必须以与INPUT语句中列出的变量相同的顺序存储。 否则,您可以使用特定于列的格式化输入。 格式化输入是最灵活的,可以处理任何数据文件。 类数据文件的INPUT语句可能如下所示:

    Infile inclass;

    Input @1 name8. @10 sex $char1. @15 age 2.0

    @20 height 4.1 @25 weight 5.1;

    这些语句指定以下内容:

    ·NAME是一个字符变量; 它的值从第1列开始(由@ 1表示)并占用8列($ CHAR8。)。

    ·SEX是一个字符变量; 其值可在第10列($ CHAR1。)中找到。

    ·AGE是一个数值变量; 它的值在第15和16列中找到,没有小数位(2.0)。

    ·HEIGHT是在第20列到第23列中找到的数字变量,隐含一个小数位(4.1)。

    ·WEIGHT是第25到29列中的数字变量,隐含一个小数位(5.1)。

    接下来的部分将讨论这两种输入模式。

    List Input

    如果数据以逗号或数据字段之间的一个或多个空格记录,则可以使用列表输入来读取数据。 如果您缺少值 - 即未知值 - 它们必须用句点(.)而不是空白字段表示。

    当SAS / IML语言查找值时,它会跳过空格和制表符。 然后它会扫描该值的分隔符。 分隔符是空白,逗号或记录的结尾。 使用&符号(&)格式修饰符时,SAS / IML会查找两个空格,一个逗号或记录的结尾。

    用于列表输入的INPUT语句的一般形式如下:

    INPUT variable <$> <&> <…variable <$> > <&> >;

    Variable

    命名要由INPUT语句读取的变量。

    表示前面的变量是字符。

    表示字符值可以包含一个嵌入的空白。 因为空白通常表示数据值的结尾,所以使用&符号格式修饰符以至少两个空格或逗号表示值的结尾。

    通过列表输入,SAS / IML扫描输入行的值。 在以下情况下考虑使用列表输入:

    当空格或逗号分隔输入值时

    当句号而不是空格表示缺失值时

     

    在几种情况下,列表输入是默认值。 这些情况的描述和SAS / IML的行为如下:

    如果没有为变量指定输入格式,则SAS / IML会扫描数字。

    如果指定了单个美元符号或&符号格式修饰符,则SAS / IML会扫描字符值。 &符号格式修饰符可以实现单个嵌入空格。

    如果格式未指定或为零,则SAS / IML会扫描第一个空格或逗号。

     

    使用列表输入读取时,INPUT语句中列出的变量的顺序必须与数据文件中值的顺序一致。 例如,请考虑以下数据:

    Alice f 10 61 97

    Beth f 11 64 105

    您可以使用列表输入通过指定以下INPUT语句来读取这些数据:

    Input name $ sex $ age height weight;

    该陈述暗示变量按给定的顺序存储。 也就是说,每行数据按该顺序包含学生的姓名,性别,年龄,身高和体重,并至少用空格或逗号分隔。

    Formatted Input

    列表输入的替代方法是格式化输入。 读取格式化输入的INPUT语句必须在每个变量后面都有一个SAS信息。 信息提供输入值的数据类型和字段宽度。 格式化输入可与指针控件和格式修饰符一起使用。 但是,格式化输入既不需要指针控件也不需要格式修饰符。

     

    指针控制功能

    指针控件重置指针的列和行位置,并告诉INPUT语句去哪里读取数据值。 您可以使用指针控件指定要从中读取的列和行:

    · 列指针控件将指针移动到指定的列。

     

    · 行指针控件将指针移动到下一行。

     

    · 行保持控件使指针保持在当前输入行。

     

    · 二进制文件指示符控件指示输入行来自二进制文件

     

    列指针控制

    列指针控制指示输入值从哪一列开始。 列指针控件以at符号(@)或加号(+)开头。 完整列表如下:

    @n

    将指针移动n列。

     

    @点变量

    将指针移动到由point-variable的当前值指定的列。

     

    @(表达式)

    将指针移动到表达式值给定的列。 表达式必须求值为正整数。

     

    + N

    将指针移动n列。

     

    +点可变

    将指针移动到由point-variable值给出的列数。

     

    +(表达式)

    将指针移动到由expression值给出的列数。 表达的值可以为正负。

    以下是使用列指针控制的一些示例:

     

    在前面使用格式化输入的示例中,您使用了多个指针控制。 以下是陈述:

    infile inclass;

    input @1 name $char8. @10 sex $char1. @15 age 2.0

    @20 height 4.1 @25 weight 5.1;

    @ 1将指针移动到第1列,@ 10将指针移动到第10列,依此类推。 将指针移动到数据字段开始的列,然后提供指定变量占用的列数的信息。 INPUT语句也可以写成如下:

    input @1 name $char8. +1 sex $char1. +4 age 2. +3 height 4.1

    +1 weight 5.1;

    在此表单中,将指针移动到第1列(@ 1)并读取8列。 指针现在位于第9列。现在,将指针+1列移动到第10列以读取SEX。 informat要读取占据一列的字符变量。 在读取SEX的值后,指针位于第11列,因此使用+4将其移至第15列,并在第15和16列中读取AGE。 指针现在位于第17列,因此移动+3列并读取HEIGHT。 同样的理念适用于阅读重量。

     

    2.3.6 DDE 方法

    DDE是一种传统方法,SAS不鼓励使用DDE。 相反,请考虑较新的SAS功能支持的替代方案。

    当您现代化到集中式SAS环境时,请注意几个挑战。 例如,如果您的SAS会话在远程计算机(通常是未在Windows上运行的计算机)上运行,则SAS无法使用DDE与本地Microsoft Excel应用程序进行通信。 DDE仅在同一台计算机上的两个Windows进程(SAS和Excel)之间工作。

    但是,只要您将SAS软件及其DDE合作伙伴(通常是Microsoft Excel)置于同一台Windows PC上运行,使用DDE的SAS程序仍然可以正常工作。

    如果您的进程依赖于DDE但需要在很短的时间内转移到客户端/服务器SAS环境,请采用以下方法。 使用SAS for Windows维护指定的计算机以执行DDE基本工作,即使将其他进程移至企业SAS环境也是如此。

    动态数据交换(DDE)是一种在Windows应用程序之间动态交换信息的方法。 DDE使用客户端/服务器关系使客户端应用程序能够从服务器应用程序请求信息。 SAS始终是客户。在此角色中,SAS从服务器应用程序请求数据,将数据发送到服务器应用程序或向服务器应用程序发送命令。

    您可以将DDE与DATA步骤,SAS宏工具,SAS / AF应用程序或请求和生成数据的SAS的任何其他部分一起使用。 DDE有许多潜在用途。一种用途是从Windows电子表格或数据库应用程序中获取数据。

    您可以通过访问以下URL来访问动态数据交换(DDE)支持的应用程序。支持Word和Excel应用程序。不支持PowerPoint应用程序。

    注意:许多Windows程序(包括SAS)现在都支持OLE以促进应用程序之间的通信。如果需要与支持OLE的应用程序共享数据,您可能更喜欢使用SAS内置的OLE支持。有关更多信息,请参阅关于OLE。

     

    要在SAS中使用DDE,请使用以下语法发出FILENAME语句:

    FILENAME fileref DDE 'DDE-triplet;

    fileref

    是一个有效的fileref(如引用外部文件中所述)。

    DDE

    是设备类型关键字,告诉SAS您要使用动态数据交换。

    'DDE-triplet'

    是DDE外部文件的名称。

     

     

     

    DDE示例概述

    本节提供了在Windows下使用DDE和SAS的几个示例。 这些示例使用Microsoft Excel和Microsoft Word作为DDE服务器,但任何支持DDE作为服务器的应用程序都可以与SAS通信。

    在运行这些示例之前,必须先调用Microsoft Excel和Microsoft Word,然后打开示例中使用的电子表格或文档。

    注意:DDE示例包含在您从"帮助"菜单访问的特定于主机的示例程序中。

     

    使用X命令打开DDE服务器

    可以使用SAS代码中的X命令打开DDE服务器应用程序。 必须关闭XWAIT和XSYNC选项。

    选项noxwait noxsync;

    x '"C:\program files\microsoft office\office14\excel.exe"'; 
    

    如果路径包含空格,则路径周围需要双引号。 单引号用于X命令。
    

     

    使用DDE从Microsoft Excel读取数据
    

    您可以使用DDE将Excel应用程序中的数据读入SAS,如下例所示:
    

    filename monthly
    

      dde 'excel|sheet1!r1c1:r10c3';
    

    data monthly;
    

       infile monthly;
    

       input var1 var2 var3;
    

    run;
    

    proc print;
    

    run
    							

    使用DDEMicrosoft Word读取数据
    							

    此示例从给定书签的Microsoft Word文档中读取数据。
    							

    filename testit dde 'winword|"c:\temp\testing.doc"
    

                         !MARK' notab;
    

     

    libname workdir 'c:\temp';
    

     

    /* Get ready to read the first bookmark.  */
    

     

    data workdir.worddata;
    

       length wordnum $5;
    

       infile testit;
    

       input wordnum $;
    

    run;
    

     

    proc print;
    

    run;
    

     

    阅读遗漏数据
    

    此示例说明从名为SHEET1的Excel电子表格中读取缺少的数据。 此示例读取第1列到第3列以及第10行到第20行中的数据。某些数据单元可以为空白。 以下是一些数据的示例:
    

    ...
    

    10   John    Raleigh      Cardinals
    

    11   Jose    North Bend   Orioles
    

    12   Kurt    Yelm         Red Sox
    

    13   Brent                Dodgers
    

    ...
    

    以下是可以将这些数据正确读取到SAS数据集中的代码:
    

    filename mydata
    

      dde 'excel|sheet1!r10c1:r20c3';
    

    data in;
    

       infile mydata dlm='09'x notab
    

              dsd missover;
    

       informat name $10. town $char20.
    

                team $char20.;
    

       input name town team;
    

    run;
    

    proc print data=in;
    

    run;
    

    在此示例中,NOTAB选项告诉SAS不要将从Excel应用程序发送的选项卡转换为空白。因此,制表符可用作数据值之间的分隔符。 DLM =选项指定分隔符,'09'x是制表符的十六进制表示。 DSD选项指定两个连续的分隔符表示缺失值。默认分隔符是逗号。有关DSD选项的更多信息,请参阅SAS系统选项参考。如果SAS程序在所有INPUT语句变量的当前行中找不到值,则MISSOVER选项会阻止SAS程序进入新的输入行。使用MISSOVER选项,当INPUT语句到达当前记录的末尾时,预期但未找到的值将设置为缺失。
    

    INFORMAT语句强制DATA步骤使用修改后的列表输入,这对此示例至关重要。如果您不使用修改列表输入,则会收到不正确的结果。使用修改后的列表输入的必要性不是DDE特定的。即使您在CARDS或DATALINES语句中使用数据,无论数据是空白还是逗号分隔,您都需要它。
    

     

    2.3.7 sas pipe

    什么是管道?

    管道使您的SAS应用程序能够从任何写入标准输出的UNIX命令接收输入,并将输出路由到从标准输入读取的任何UNIX命令。 在UNIX命令中,管道由竖线(|)表示。 例如,要查找目录中的文件数,可以通过管道将ls命令的输出重定向到wc(字数)命令:

    ls | wc -w

     

    命名管道简介

    命名管道功能是Windows中用于与其他应用程序通信的SAS中最强大的工具之一。 命名管道功能可以在同一台计算机上的应用程序或网络上不同计算机上的应用程序之间进行双向数据或消息交换。

       在SAS实际工作中经常会遇到需要批量导入某文件夹下的所有excel文件,或者需要读取某文件夹下最新的文件。这种情况下即需要扫描文件夹下的所有文件,以便于后续程序的批量操作或者判断,我们可以扫描读取文件夹下所有文件名称:利用pipe管道来实现。

     pipe管道方法无需其他的函数参与,仅需要filename和pipe即可实现。

    例子:

    现在需要读入"D:\user\input\"文件夹下的所有xls后缀文件名。

    程序:

    filename msg pipe "dir D:\user\input\*.xls /b /s";  /*/b /s是dos中的命令,/b表示使用空格式即只输出文件名,/s表示文件夹下的子文件夹的所有文件也进行扫描*/

    data temp_excel;

            infile msg;

            length myname $200.; /*定义myname的格式以及长度*/

            input myname;

    run;

     

    至此,生成的temp_excel数据集中即包含"D:\user\input\"路径下的所有xls后缀的文件名。

    此外可以在data步加上一些where条件也是可以的。

    比如:只想读取包含"销售日报"的文件,那么data步只需要稍做修改即可。

    data temp_excel;

            infile msg;

            length myname $200.; /*定义myname的格式已经长度*/

            input myname;

            if index(myname,"销售日报")  gt 0;  /*添加的条件:只选取包含"销售日报"四个字的文件*/

    run;

     

    这里用到的语法如下:

     

    filename pipe "";

     

    其中command是DOS命令,pipe将command里面的信息导入虚拟文件fileref里面,再在data步里面调用。例如我们需要读取电脑里面一个文件夹(D:\TEMP)下面所有的txt文件:

    filename temp pipe "D:\TEMP\*.txt /b";

     

    2.3.8 IO 函数

    直接I / O是一种处理输入和输出文件的方法,用于文件处理。直接I / O使SAS能够直接从存储设备读取文件并将文件写入存储设备,而无需先通过UNIX操作环境的读写缓存。您可以将直接I / O用于SAS文件。使用直接I / O可能会提高系统性能,具体取决于您运行的作业的数量和类型。

     

    SAS使用三个影响直接I / O的相关选项:

     

    ENABLEDIRECTIO声明选项

     

    USED??IRECTIO =声明选项

     

    USED??IRECTIO =数据集选项

     

    LIBNAME语句中的ENABLEDIRECTIO选项使直接I / O处理可用于DATA语句中列出的数据集。指向数据集的libref必须已在使用ENABLEDIRECTIO选项的LIBNAME语句中定义。使用ENABLEDIRECTIO本身不会打开直接I / O.

     

    分配给具有ENABLEDIRECTIO选项的目录的libref将与没有ENABLEDIRECTIO选项分配给同一目录的另一个libref不匹配。两个libref将指向同一目录,但使用带有ENABLEDIRECTIO的libref打开的文件将使用直接I / O读取和写入。使用常规磁盘I / O调用将读取和写入使用其他libref打开的文件。

     

    DATA语句中的USEDIRECTIO =数据集选项或LIBNAME语句中的USEDIRECTIO =语句选项为已应用ENABLEDIRECTIO语句选项的数据集启用直接I / O.在不首先应用ENABLEDIRECTIO选项的情况下使用USEDIRECTIO =对数据集中的直接I / O没有影响。

    您可以通过两种方式打开直接I / O:

     

    在LIBNAME语句中同时使用ENABLEDIRECTIO和USEDIRECTIO =选项。

     

    此方法打开直接I / O LIBNAME语句中libref引用的所有文件。

     

    使用LIBNAME语句中的ENABLEDIRECTIO选项呈现可用的直接I / O,并使用DATA语句中的USEDIRECTIO =数据集选项打开直接I / O功能。

     

    此方法仅针对LIBNAME语句中libref引用的数据集的直接I / O打开。

    这种方法导入数据比较少见具体参考SAS help帮助文档。

     

    2.3.9 Import Wizard 使用导入向导

    SAS还可以通过界面导入各种类型的数据

    1 点击 文件>>>导入数据

     

     

     

     

    2 选择格式

     

     

     

    3 选择好后点击 NEXT >>>的、选择文件所在的位置,然后点击 打开 ,点击NEXT

     

     

     

     

    4 选择逻辑库(默认是WORK)和要生成数据集的名称(aa),点击 Finish

     

    然后在WORK逻辑库中会有aa数据集,窗口日志也会显示创建成功。至此,数据导入成功!

    其它格式数据的导入跟上例类似,请自行操作。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

SAS