SAS编程演义
上QQ阅读APP看书,第一时间看更新

3.6 读取流式数据

数据库文件由于数据库管理软件有严格的格式限定,因此数据规范整齐,用LIBNAME语句配合数据库引擎即可轻松访问,PC格式数据文件,基本也有章可循,因此基本上只需要直接套用PROC即可。最麻烦的是数据直接放在SAS程序DATA步的DATALINES下,这种称为流式数据的读取是最需要灵活性的,因此设置也更为复杂,庆幸的是,这种方式通常只是用来做一些简单的测试,在真正的项目实践中并不会常用。

→3.6.1 流式数据初探

对于流式数据读取,其实在第2章讨论@与@@的区别时已经展示过。在此,我们再举一个非常实用的场景:在做卡方检验录入四格表数据时,我们不必要一人一行地录入,我们可以按四格表的格子分别录入频数统计的数据。例如,试验组存活95例,死亡5例;对照组存活90例,死亡10例。我们不必输入200行数据,采用DO循环和INPUT以及@@,读入一行数据就可以解决。

程序3-7 INPUT语句输入四格表数据

    datatrial;
      do group="T","C";
        do Survive="Yes","No";
          input freqs@@;   /*从Datalines读入数据*/
        output;            /*写入数据到数据集*/
        end;
      end;
    datalines;
    95 5 90 10
    ;
    run;


    *检查四格表结果;
    proc freqdata=trial;
        table group*survive/nopercent norow nocol ;
        weight freqs;
    run;

→3.6.2 INPUT语句一般语法

上面只是简单示例如何用INPUT语句,细究起来,INPUT语句的语法其实是比较复杂的。其复杂性和多样性主要体现在输入申明(SPECIFICATION)里。一般的INPUT语句的语法可参考语法3-4。

语法3-4 INPUT语句一般语法参考卡片

在输入申明里,我们可以指定变量或者变量列表。在变量前,我们可以进行指针控制,在变量后,我们可以进行列位置限定、格式修饰以及指定读入格式等。因此,Input语句在具体使用时有列表读入、列读入、格式读入以及命名读入四式。

→3.6.3 列表读入式

所谓列表读入式,顾名思义,即简单地按变量在DATALINES数据行里出现的顺序列出所要读入的变量名,当然,也可以在变量名后面适当增加格式或者格式修饰符(如「:」,「&」或者「~」)。这种读入式适合数据并不齐整(读入的变量无法整齐的固定在某个列范围,如1~5列),但是变量间都规律的以一个或者多个连续字符(可以是空格或者其他字符)作为分隔符的情况。具体情况大家可以琢磨下语法3-5。

语法3-5 INPUT语句列表读入式语法参考卡片

程序3-8 INPUT语句列表读入式案例

    *==变量列上不齐整;
    datatmp;
      input name $   gender$   age location $;
      datalines;
    GHQ M 30 Beijing
    TJSW M 1 Beijing
      ;
    run;


    *===字符name不齐整且字符长度过8;
    datatmp;
      input name :$13.   gender$   age location $; /* :表示碰到空格或者第13列,才
    读完name变量的数据 */
      datalines;
    GHQ M 30 Beijing
    GuHongqiu M 30 Beijing
    StatsThinking M 1 Beijing
      ;
    run;


    *===字符name里有空格;
    datatmp;
      input name & $   gender$   age location $; /* &碰到一个空格不会认为此变量结
    束,还会继续读入 */
      datalines ;
    HQ Gu   M 30 Beijing
    TJ SW   M 1 Beijing
      ;
    run;


    *===字符name里有空格且字符长度过8;
    datatmp;
      input name : & $10. gender$   age location $;
      datalines ;
      HQ Gu   M 30   Beijing
      Hongqiu Gu   M 30   Beijing
      ;
    run;


    *===其他分隔符数据,字符affiliation含有分隔符;
    datatmp;
      infile datalines delimiter=',';
      input name $   gender$   age location $ affiliation $12.;
      datalines ;
      HQ Gu,M,30,Beijing,"PUMC,CAMS"
      Hongqiu Gu,M,30,Beijing,"PUMC,CAMS"
      ;
    run;

→3.6.4 列读入式

除了简单列出要读入的变量名的列表外,在变量名后指定变量的输入起止列,这种读入方式比较适合数据齐整的情况,其优势是变量顺序已不重要,而且待读入的数据可以重复利用,多次读入,此外字符变量还可以包含空格。

列读入式语法参考语法3-6。

语法3-6 INPUT语句列读入式语法参考卡片

程序3-9 INPUT语句列读入式案例

    *===列读入;
    datatmp;
      input name $ 1-10  gender $ 12  age 14-15location $ 17-23;
      datalines ;
    HQ Gu       M 30 Beijing
    Hongqiu Gu M 30 Beijing
      ;
    run;

→3.6.5 格式读入式

除了简单列出要读入的变量名的列表,在变量名后指定变量的输入格式。这种读入方式可以对字符变量指定宽度,以及读入非标准形式的数字,如科学计数法、带货币符号、带千分位,等等。

格式读入式语法参考语法3-7。

语法3-7 INPUT语句格式化读入式语法参考卡片

封面

    *===格式读入;
    *===gender虽然只有1列,但是申明时要带上其后面的一个空格,age,locaiotn类似;
    datatmp;
      input name : & $10. gender$2.   age 3.   location $8. fee comma6. ;
      datalines ;
      HQ Gu   M 30 Beijing 12,345
      Hongqiu Gu   M 30 Beijing 54,321
      ;
    run;

→3.6.6 命名读入式

如果在申明变量时,采用「变量名=」的形式,就成了命名读入式。需要留意的是,在DATALINES的数据行里,数据的形式也应该为「变量名=变量值」的形式。命名读入式语法参考语法3-8。

语法3-8 INPUT语句命名读入式语法参考卡片

程序3-11 INPUT语句命名读入式案例

    *===命名式;
    data tmp;
      input name= $   gender= $   age= location= $;
      datalines;
    name=GHQ gender=M age=30   location=Beijing
    name=TJSW gender=M age=1 location=Beijing
    ;
    run;

INPUT语句可以很简单,也可以组合得很复杂。上面只是简单展示了INPUT语句读入四式的使用,其他更具体复杂的例子大家可以参考SAS Help。

在实际应用中,很少单纯去用一种读入式,基本上都是组合式。不过笔者个人仍坚持认为没有必要太过在意INPUT语句读入数据的各种复杂形式,究其原因是:现在的数据体量增长迅速,不适合在DATALINES场景下读入,此外数据库管理软件的应用也越来越普遍,单纯依靠DATALINE读入数据的场景也越来越少。

→3.6.7 DATALINES数据综合案例

我们看一个综合的案例来体会INPUT语句组合式的用法。

程序3-12 INPUT语句组合式读入案例

    *===综合案例;
    datatmp;
      input name : & $10. gender $   age location $ 17-24 +1fee comma6. ;
      datalines ;
    HQ Gu         M 30 Beijing 12,345
    Hongqiu Gu   M 30 Beijing 54,321
    ;
    run;

→3.6.8 关于列表、指针及格式等

我们对变量列表、指针、列位置、格式修饰符以及输入格式做下简单介绍。因为这些概念不仅流式数据读取时有用,在其他地方也经常使用。

● 变量列表是指一些列的变量清单,在SAS里,变量列表有四种。

■ 编号范围列表,形如x1,x2,x3,…,xn的这一系列变量可简写为「x1-xn」。

■ 名称范围列表,这种列表依赖于变量定义的顺序。这种顺序可以打开数据集直接查看,也可以右击数据集点击「查看列」查看,或者如前面2.3.2节介绍的用PROC CONTENTS查看。「x--a」即指定义顺序为从x到a的所有变量,「x-numeric-a」则为从x到a的所有数值型变量,「x-character-a」则为从x到a的所有字符型变量。

■ 名称前缀列表,如x_1,x_2,…,x_3或者x1,x2,…,x3都可简写成「x:」。

■ 特殊SAS名列表,如_numeric_,_character_,_all_分别表示所有数字型变量、字符型变量、所有变量。

● 对于变量前的指针(我们可以简单理解为地址),主要作用是指定读入变量的起始位置。我们可以用#或/在行上做位置控制,这便是所谓的行指针。#是具体跳到某一行,/是跳到当前行的下一行的第一列;当然,我们也可以用@或+在列上做位置控制,这便是所谓的列指针。@是具体跳到某一列,+是从当前列开始跳列。@后面如果是字符串常量或者字符变量的话,@相当于一个检索功能符,会将列指针跳到读入记录里这个字符串或者字符变量里所包含的字符串后面的第一列。

● 列位置即指定读入数据的位置为从多少列到多少列。如input name$1-8表示在1~8列读入数据存为变量name。

● 格式修饰符的主要作用是在列表读入式时,对读入规则做一些细微调整。

● 输入格式指定读入变量时应遵循的规则。