关于input的columninput (列输入)和listinput (列表输入).

关于inputcolumninput (列输入)listinput (列表输入).

简单来说:列输入就是严格按照变量指定的长度进行数据读取,忽略分隔符。如input name 1?10;  inputhome40.; 都属于列输入。列表输入就是根据规定的分隔符(默认是空格)按照变量的顺序读取数据,多个空格按照一个处理,遇到空格即停止。如input name home:40. ;

假设有如下原始数据:


需要注意的是,在windowsunix中的文本处理器如写字板创建上面的数据,数据每行属于可变长度,每行的长度就是灰色区域的长度,而在sasdatalines中,上述的数据是固定长度的,长度为80 bytes,后面没数据的地方以空格填充,在大型主机的某些数据文件中,数据行也是固定长度的,无数据的地方以空格填充。


首先分别以input的列输入和列表输入导入上述数据,假设数据位于dinfile文件夹中,名字为emplist



DATA test1;   /*column input*/

    INFILE "d:\infile\emplist.dat";

    INPUT lastn $1-21 Firstn $ 22-31

        Empid $32-36 Jobcode $37-45;

RUN;


DATA test2;   /*list input*/

  INFILE "d:\infile\emplist.dat";

  INPUT lastn Firstn

          Empid Jobcode ;

RUN;

上述程序提交后,结果如何,在此之前,先讲一下flowover选项Infile默认是flowover选项。

在列输入时:如果input指针到了一行的最后一个字符时,有些变量还是没有得到值或者完整的值,指针就会跳到下一行的第一列开始读取数据,来填充没有值的变量。当下次input语句执行的时候,新的一行数据就会进入inputbuffer

因此列输入数据如下:


说明,对于第二行数据,pilot没有达到jobcode所需要的长度,因此指针跳到下一行读取smith填补上来。完成之后进入数据步的下一个循环,执行下一次input,因此指针再次跳行,将leistner读入。而读取第五行tomas数据时,harald长度不够firstn用,所以指针跳到下一行将wade读入作为firstn,然后e1026作为empidpilot仍然不够用,所以跳到下一行读取waugh作为jobcode;

在列表输入时,以空格为分隔符,数据可以正确地读入,但默认的flowover选项仍然会导致将下一行数据读入填充缺失值。结果如下:


使用missover选项:

当在infile语句中使用missover选项时,它会抑制掉flowover,使得在读取短的数据行时,input指针不会跳到下一行来读取数据,相反,它使得没有数据的变量变缺失。

在列输入中加上missover选项时,结果如下:



我们发现的是,再也没有从下一行读取数据,可是jobcodepilot和第6行的后面仍然没有正确读入。这是因为在列输入的时候,如果指针到了一行的结尾,仍然没能读入满足变量长度的数值,就会将该变量变缺失。解决方法:可以再加入pad选项,pad选项数据后面填上空格,使得每行的长度相同,默认lrecl=256

如果列表输入infile加上missover选项,结果如下,不会像列输入那样将最后的变量变缺失。



Truncover: 其实truncover的功能类似于missover pad合用的效果,它是针对列输入时,如果一行最后读入的数值仍然不能满足变量需要的长度,不会将变量缺失,而是将读入的值赋给该变量。列输入加truncover的结果同上。

当然,对于列表输入,truncover的结果也同上,是正确的结果。

关于PADpad固名思义,意思是将数据行的后面部分填上空格,这样就使得数据行变长,不致于让input指针在读取短数据行时到达数据行结尾从而跳行。Pad不会抑制flowover的作用,它会将数据后面的空白位置填上空格,空格的长度由lrecl=n决定,默认n256,当然可以在infile选项中修改n的大小。这就是为什么在列输入中用missoverpad可以正确读取数据了,因为数据行的长度不再是数据实际的长度(可变长度),而是一个固定长度256,后面都是空格。

如果列表输入只加pad,不加missover,结果如下


Pad不会抑制flowover,并且将多个空格作为一个处理,所以出现了上述结果。



关于读取外部文件和datalines中的区别,很多朋友都发现sas读取外部文件和datalines数据,数据结构完全一样,同样的程序,结果不同。

原因是:外部文件数据,数据行是可变长度,如上例。除非加上pad,以空格填充。

而在cards中的数据,看起来也是可变长度,但其实是固定长度,为80。结尾没有数据的地方都以空格填充。即默认有pad 。引用davil2000大神的回答:

Cardimagesystem option specifies that SAS source and data lines be processed as if thesewere punched card images—all exactly 80 bytes long and padded with blanks.

所以如下两个程序:

data test3;

input lastn $1-21Firstn $ 22-31

        Empid $32-36 Jobcode $37-45;

cards;

LANGKAMM             SARAH     E0045 Mechanic

TORRES               JAN       E0029 Pilot

SMITH                MICHAEL   E0065

LEISTNER             COLIN     E0116 Mechanic

TOMAS                HARALD

WADE                 KIRSTEN   E0126 Pilot

WAUGH                TIM       E0204 Pilot

;

run;

data test4;

input lastn Firstn

      Empid Jobcode ;

cards;

LANGKAMM             SARAH     E0045 Mechanic

TORRES               JAN       E0029 Pilot

SMITH                MICHAEL   E0065

LEISTNER             COLIN     E0116 Mechanic

TOMAS                HARALD

WADE                 KIRSTEN   E0126 Pilot

WAUGH                TIM       E0204 Pilot

;

run;

列输入可以正确读入,列表输入不行,因为没有missover选项,类同于读取外部文件时只加pad选项。

你可能感兴趣的:(sas)