我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:港彩神鹰 > 读入数据 >

通过DATA步读取数据(二):初级

归档日期:04-23       文本归类:读入数据      文章编辑:爱尚语录

  本文转自SAS知识 (ID: SASadvisor),摘自《深入解析SAS — 数据处理、分析优化与商业应用 》

  上一篇文章介绍了DATA步的处理过程,今天我们介绍通过DATA步读取外部文本文件的六种输入方法。

  在使用DATA步读取外部文本文件中的数据时,需要给SAS提供读取原始数据所要求的特定信息,例如原始数据的位置、数据集变量和类型,以及SAS如何读数据等,SAS会根据这些信息创建数据集。

  在DATA步中可以使用DATALINES直接输入数据或通过INFILE语句指定原始数据文件。本文之前的示例代码所给出的都是通过DATALINES直接输入数据。但在实际应用中,要分析的原始数据往往存储在外部文件中。这篇文章主要介绍使用DATA步读取外部文本数据文件中的数据。

  在读取原始数据文件并创建SAS数据集之前,必须先检查原始数据文件,确定要读取的数据值在原始数据记录中的格式,并基于这些信息选择读取数据时使用的方法。SAS提供了三种基本输入方式:

  这三种输入方式可以单独使用,也可组合使用,还可以和SAS提供的各种修饰符以及指针控制结合使用,例如与输入格式、行抑制符、行指针控制和列指针控制一起使用。

  INFILE语句指定原始数据的位置和名称。原始数据文件可以是在FILENAME语句中定义的文件引用形式或操作系统下的文件路径。

  这里简单介绍如何使用FILENAME定义文件引用。在INFILE语句中可直接使用带路径的外部文件名称,也可以使用事先由FILENAME语句赋值的文件引用。使用FILENAME语句可以将SAS文件引用与外部文件或者存储位置(存储有多个外部文件)关联起来,其基本形式如下:

  其中“文件引用”用于指定文件引用的名称,以字母开始,可包含字母、数字和下划线个字符。“外部文件”则给出了一个带完整路径名的外部数据文件的文件名,或者一组文件的存储位置。下面分别给出在Windows环境下,FILENAME语句指定单个文件和一组文件的存储位置定义,以及在INPUT语句中如何使用这两种的文件引用。

  列表输入(List Input)用于读取原始数据记录中每个字段由至少一个分隔符隔开,并且数据值中不包含该分隔符的原始数据。列表输入默认分隔符为空格,连续的分隔符会当成一个分隔符处理,INPUT语句中包含了简单的变量名称列表。使用列表输入的基本形式如下:

  变量1、变量2等:是数据集的变量,变量与变量之间用空格分隔。对于字符变量则需在变量后加字符$。INPUT语句顺序地将原始数据记录中由空格隔开的数据值读入到所列出的变量中。

  当原始数据记录中的数据值以一个或多个空格隔开,且数据值中不包含空格时,可使用默认的列表输入方式。

  本文所有的示例中,都假定已经为逻辑库引用名saslib指定了SAS逻辑库,而且为文件引用名extfiles指定了所有外部数据文件所在的位置。

  INPUT语句会逐行顺序地读取inventory.dat中的数据值,并赋值给变量。在读取每行数据时,遇到空格就停止读入当前数据值,并从非空格处读入下一个数据值。

  使用列表输入时,字符变量长度默认为8个字节。当输入数据长度超过8个字节时,从输入缓冲区读入PDV的数据值会产生截断。这个问题可以通过在INPUT语句之前使用LENGTH语句指定该变量的长度或其他方式来解决。

  SAS遇到空格时会停止读入当前数据值,这样SAS就不能处理原始数据记录中的数据值包含空格的情况了。

  通常在变量第一次出现时程序会根据上下文环境确定其长度。可以在INPUT语句前通过LENGTH语句明确指定变量长度。

  要读入的数据文件state.dat中的原始数据记录如下,在该记录中州名全称字符长度超过了8个字节。

  PRINT语句打印的数据集内容如图2.25所示,可以看到,第一条和第二条记录中State变量的数据值不全,都出现了截断。

  可在INPUT语句前加入LENGTH语句,指定State变量的长度为20个字符。修改后的SAS代码如下:

  这时,PRINT打印的数据集的内容如图2.26所示,这时State变量中的州名完全写入数据集中了。

  你可能已经注意到,打印的数据集中变量的顺序发生了变化。这是因为它们的顺序由DATA步中变量出现的顺序决定,而State变量首先在LENGTH语句中出现,接着INPUT语句才会出现Short_Name。但是,这并不影响数据值的读入顺序。在列表输入方式下,读入的数据值顺序由其在INPUT语句中出现的顺序确定。

  当原始数据中数据记录的数据值未使用空格,而是使用其他分隔符时,需在INFILE语句中使用DLM=选项,告诉SAS读入数据时需要使用的分隔符。

  下面将上面外部数据文件的内容稍作修改以便比较。文件inventory_dlm.dat的内容如下,数据记录中的各数据值之间由逗号(,)隔开:

  使用DLM=选项可处理原始数据记录中数据值中包含空格的情况。此外,使用DLM=选项的DATA步也可以很好地处理数据中的缺失值。如果接连有多个指定的分隔符,也会当成一个分隔符处理。但如果分隔符之间有空格,则该空格会当作缺失值读入变量并写入数据集。例如,当数据文件inventory_missing.dat的内容如下时:

  提交与上例相同的SAS代码,记得将外部数据文件名字改为inventory_missing.dat。PRINT过程打印的数据集内容如图2.27所示,其中第三个观测Instock变量为默认值。

  指定选项DSD后,如果数据值是由引号引起来的,可以将数据值中的分隔符当成是数据值的一部分读入,字符值中的引号在读入PDV时会被删除。DSD选项将默认的分隔符设置为逗号,还改变了使用列表输入时SAS处理分隔符的方式,比如,如果有两个连续的逗号,将被当作缺失值。

  原始数据文件customer_dsd.dat的内容如下,其中客户的地址信息中包含了逗号,并使用双引号引起来,第一条和第三条记录中的客户名字缺失。

  读取该外部数据文件的SAS代码如下,代码中还使用了LENGTH语句指定变量长度。

  PRINT过程打印的数据集内容如图2.28所示。同样,因为SAS先编译到LENGTH语句,所以数据集中Name和Address变量出现在Customer_ID前面了。

  选项DSD还可以和其他选项(例如DLM=和DLMSTR=)一起使用。DLM=在上面介绍过,DLMSTR=用于指定分隔数据值的字符串。如果需要,可以查看SAS帮助文档获得更多信息。

  当原始数据记录中的数据值在每条记录中占据相同的列时,可使用按列输入的方式。按列输入(Column Input)可以读取固定列的数据。该读入方式的INPUT语句基本形式如下:

  在列表输入方式下,读入的数据值由指定的列号确定,所以使用列表输入可以以任何顺序读入列,而且可跳过一些列,不读入到数据集中或重读数据记录中的数据值。

  上面介绍的按列输入与列表输入一样,只能读取标准的字符或数字值到数据集中。其实,SAS还可以读取特殊格式的数字数据,例如二进制数据、日期/时间(01FEB2013),或者包含逗号(1,262)、货币符号($87.3)等特殊字符的数字值。在这种情况下,就需要使用格式化输入(formatted input)了,即在INPUT语句中提供特殊的指令,以便SAS正确地读取原始数据记录中的数据值。这些特殊指令称为输入格式(Informat)。格式化输入组合了按列输入特征和读取非标准化数字或字符值的能力,保证数据值可正确地从原始数据记录中读入。

  数字型和字符型最基础的输入格式形式分别为n.和$n,例如10.和$20.,表示从输入缓冲区的当前列控制指针处分别读取10列和20列,并赋值给对应变量。对于字符变量,输入格式还指定了变量的长度,而数字型变量的长度仍然为8。

  除了这些基础的格式外,SAS还提供了一些格式用于读入特殊格式的数字值,例如前面提到的读入带$符号的数字或日期时间值。同时,SAS还支持自定义格式,在本书后面的章节会学习到。

  来看个示例,原始数据文件sales.dat的内容如下,该文件中原始数据记录包含字段依次为员工ID、部门、销售额和上次修改日期,其中销售额和日期都不是标准数字值,需使用对应的输入格式。

  读入处理该文件的SAS代码如下,其中Sales和Date变量分别使用了输入格式comma6.和date9.,Emp_ID和Dept使用的是上面介绍过的按列输入方式。

  PRINT过程打印的数据集内容如图2.30所示。SAS的日期、时间以数字形式存储。所以打印的数据集中Date变量的值为数字,其实可通过输出格式(format)输出为更加易读的形式。

  SAS提供了commaw.和datew.等很多格式,用于读取对应的带嵌入符号和日期的数字值,其中的w表示读入数据的总宽度,包含美元符号。输入格式将数据值中嵌入的$符号转换成了不带美元符号的数字值写入到PDV中,并最终写入数据集(如图2.31所示)。

  在INPUT语句中,还使用了相对列控制符号+1和绝对列控制符号@22,分别表示将当前的输入列控制指针向前移1位和将该指针直接移动到列22。在上面的示例中,程序读入一行记录到输入缓冲区后,列控制指针的移动情况如下:

  开始读入comma6.中指定的6列,即将第11~16列使用输入格式转换后写入Sales,这时列控制指针在第17列。

  @22将控制指针直接移到第22列,读入date9.中指定的9列,即第22~30列,然后使用该输入格式进行转换,并写入Date。

  SAS还提供了丰富的输入格式供SAS读入各种形式的数据值。下面给出了SAS提供的常用数字、字符、日期、时间、日期时间输入格式,见表2.1和表2.2。关于这些输入格式的详细使用方法,请参考SAS帮助文档学习。

  在学习格式化输入时,我们知道了输入格式的概念。将列表输入、输入格式和修饰符结合起来,结合后就成了带修饰的列表输入(modified list input),该方式可以更灵活地读入数据。前面讲到列表输入时,提到列表输入的一些限制,例如所创建的变量长度为8个字节、默认(分隔符为空格时)不能读入包含嵌入空格的数据值、不能处理带特殊字符的数字值和日期等。SAS提供如下格式的修改符来消除这些限制,进而增加列表输入的灵活性:

  &修饰符(ampersand format modifier):使用列表输入时,该修改符能够读入数据值中包含一个或多个嵌入空格的字符值,并指定字符的输入格式。SAS读入数据直到遇到两个连续的空格、或达到所定义的数据长度或输入行结束才停止。&修饰符解决了使用列表输入方式读取数据值中包含嵌入空格的问题,但要求该包含空格的数据值与下一个数据值之间至少间隔两个空格。

  :修饰符(colon format modifier):使用列表输入时,该修改符可以在变量名后指定输入格式。SAS读入数据直到遇到空列、达到所定义的数据长度(对字符型变量来说)或输入行结束才停止。:修饰符可以读取超过8个字节的字符数据和包含特殊字符的数字字符。

  ~修饰符(tilde forat modifier):可以读入并保持数据值中的单引号、双引号和分隔符。

  接下来通过示例来学习修饰的列表输入。注意,下面的示例中没有使用~格式修改符,有兴趣的可参考SAS帮助文档进行学习。

  原始数据文件customer2.dat的内容如下,每条记录包含联系人信息、客户ID、名字和出生日期,其中名字里面嵌入了空格,可使用&修饰符读入。注意,使用&修饰符要求名字和出生日期之间为两个空格。

  处理该数据的SAS代码如下,其中,Name变量使用了&修饰符读入带空格的名字,并指定输入格式为$20.,所以Name变量的字符长度为20个字节,而且SAS会将缓冲区中的20个字符读入Name。Birth_Date使用了:修饰符读入日期格式的数据。

  PRINT过程打印的数据集如图2.32所示,所有数据值都正确读入到了数据集中。

  命名输入(named input)读取包含变量名、等于符号和变量值的输入数据,例如Name= Willam。命名输入的基本形式如下:

  使用命名输入方式时,INPUT语句从输入指针的当前位置读取输入数据。如果原始数据记录开始处不是命名形式,则可以在开始部分使用其他输入风格,接着再使用命名方式读入数据。但是,一旦INPUT语句开始使用命名输入方式,接下来的数据值则必须也是命名形式。

  例如,原始数据文件named.dat内容如下,第二、三个字段为命名形式。

  使用命名输入读入第二、三个字段Name和Age,第一个字段Customer_ID变量使用列表输入。代码如下:

  命名输入还可以和其他语句(例如LENGTH语句定义变量长度)以及其他输入方式结合提供更多的灵活性来读取外部数据文件。

  在使用INPUT语句时不限于使用一种输入方式,可以在一条INPUT语句中混合使用这些输入方式,只要可以适当地描述原始数据记录就行。在前面格式化输入的示例中已经组合了按列输入方式和格式化输入方式,这里再将三种基础输入方式组合。

  原始数据文件mixedinput.dat的内容如下,其中依次包括了课程编号、课程名称、开课日期和报名人数等信息。

  PRINT过程打印的数据集内容如图2.34所示,各个数据值都被正确地从数据文件读入,并写入数据集。

  本文结束,下一篇文章将会介绍“通过DATA步读取数据(三)”之“读取外部文本文件中的数据(高级)”。

  如若转载本文,请在文章顶部标注 “本文转自SAS知识 (ID: SASadvisor),摘自《深入解析SAS — 数据处理、分析优化与商业应用 》”

  《深入解析SAS — 数据处理、分析优化与商业应用》第一作者, SAS软件研究开发(北京)有限公司客户职能部总监。在承担研发工作的同时,夏及其团队负责对SAS非英语市场提供技术支持,并且与在美国及其它地区的团队一起,服务于SAS的SaaS/RaaS业务,同时提供和验证关于SAS产品和技术在应用领域的最佳实践。在加入SAS软件研究开发(北京)有限公司之前,夏就职于SAS中国公司,历任资深咨询顾问、项目经理、首席顾问、咨询经理,拥有丰富的咨询和项目实施经验。在长期的从业经历中,不但为SAS的金融行业客户成功实施了众多深受好评的项目,而且在近年领导实施了非金融行业的多个大数据分析项目。

本文链接:http://chuyenchame.com/durushuju/95.html