数据清洗DATA CLEARING之infile选项之一 DSD DLM

SAS做其数据分析起来感觉很爽,但是实际中总会遇到一些格式花样很丰富的源数据,怎么把它读入到SAS内部作为逻辑库里面的一个数据集呢?不会要手动一个一个的使用健盘上的ctrl+v,ctrl+c,backplace,delete的快速调整吧。数据少的时候还可以做做,一旦数据量巨大的时候,恐怕找个机器人也会感觉费电的。其实SAS提供了很多灵活的接口,快速的解决这些dirty的数据,让他们规规距距的转化为SAS自定义的格式。
 
我们很喜欢读入这样的源数据:
 M        50      68        155
 F        23      60        101
 M        65      72        220
 F        35      65        133
 M        15      71        166
 
代码如下:
  data demographics;
     input Gender $ Age Height Weight;
  datalines;
 M        50      68        155
 F        23      60        101
 M        65      72        220
 F        35      65        133
 M        15      71        166
  ;
run;

但是这种以间隔符号“ ,”为分隔符的源数据,也很常见:

 M,50, 68,155
 F,23, 60,101
 M,65, 72,220
 F,35, 65,133
 M,15, 71,166

这时就需要用到infile及其option来读入这样的数据。
 data demographics;
  infile datalines dlm=’,’; /*     infile datalines dsd; /*也可以用这个替代*/ */
  input Gender $ Age Height Weight;
  datalines;
 M,50, 68,155
 F,23, 60,101
 M,65, 72,220
 F,35, 65,133
 M,15, 71,166
  ;
run;
 
下面这种的这种格式也是会遇到的:
  "M",50,68,155
  "F",23,60,101
  "M",65,72,220
  "F",35,65,133
  "M",15,71,166
 
如果继续用option:dlm=’,’的话,得到的数据集里的变量Gender的值有引号。可是我不需要引号,这时只用option:dsd就可以解决这个问题,如下:
  data demographics;
     infile datalines dsd; 
     input Gender  $ Age Height Weight;
  datalines;
  "M",50,68,155
  "F",23,60,101
  "M",65,72,220
  "F",35,65,133
  "M",15,71,166
  ;
run;
 
当然有时候你需要引号,那就继续使用option:dlm=’,’就可以了。当然下面使用option:dsd也可以的,需要在变量Gender后面加上一个’~’符号就可以了,如下:
  data demographics;
     infile datalines dsd; 
     input Gender ~  $ Age Height Weight;
  datalines;
  "M",50,68,155
  "F",23,60,101
  "M",65,72,220
  "F",35,65,133
  "M",15,71,166
  ;
run;
 
sas似乎会提供了多个方法途径来解决同一个问题,看起来很罗嗦。于是下面我们来看看这样的一个源数据。
 
  "M,12",50,68,155
  "F,11",23,60,101
  "M,22",65,72,220
  "F,21",35,65,133
  "M,31",15,71,166
 
如果仍然要求变量个数不变,dlm=’,’似乎不能很好的解决这个问题,它会机械的把括号里面的逗号折开,导致读入失败。如果用option:dsd就不会出现这种情况,代码如下:
 
  data demographics;
     infile datalines dsd; 
     input Gender ~ $ Age Height Weight; /*如果不需要保留双引号,可去掉修饰符~*/
  datalines;
  "M,12",50,68,155
  "F,11",23,60,101
  "M,22",65,72,220
  "F,21",35,65,133
  "M,31",15,71,166
  ;
run;
 
这个例子说明SAS不会很罗嗦的用多个途径来解决一个问题,在进行其他编程时,也有这种感受。也许可以通过多种方法来达到同一个目的,但是不表示这些方法之间没有差异,每种方法有其根源,在实现方式,思想和执行性能等各方面都会表现出差异。有时候会是极微小的差异,这里我们没有必要去吹毛求疵的去辨别这些差异,并以此为乐。寻找一种合适的解决问题编程途径是根本目的,因此了解和认识sas提供的各种方法的基本功能是最主要的,本例中,在sas/help中DSD的tips写得很清楚它会在存储数据前会去掉引号,如果想继续保留,可以加上格式修饰符"~"。
 
除此之外,option:DSD会把两个连续的","分隔符之间认为是缺失值,而option:dlm=’,’则把他们当作一个’,’来对待。你可以尝试运行一下下面的代码:
  data demographics;
/*     infile datalines dsd; */
  infile datalines dlm=’,’;
     input Gender ~$ Age Height Weight;
  datalines;
  "M,12",50,68,155
  "F,11",23,60,101
  "M,22",65,72,220
  "F,21",35,65,133
  "M,31",15,71,166
  ;
run;
 
小结:1,infile的选项:dlm=’ list-of-delimiting-characters”,引号里面还可以是其他很多类型的分隔符号(除了空格),还可以结合infile的其他选项来完成dirty源数据的读取。选项DSD是针对有逗号分隔符号的,功能很强大。为什么逗号会有这么好的待遇呢?需要一个专门的option来“伺候”它?^_^
         2,SAS有看似罗嗦烦杂的各种介绍和tips,这都是为了应对实际中的数据丰富多样化的需要产生的。
 
 
补充:SAS9.2中出现了新的选项:DLMSTR= ,有关描述和例子如下:
 
String Delimiter
 1, "Top 10" SASware Ballot Item
 2,Difficult to parse multi-character delimiters
 3,INFILE DLMSTR=
 4,Works like DLM=
data _null_;
infile mydata dlmstr=’–‘ dsd;
input x y name $ addr:$16.;
put x= y= name= addr=;
datalines;
1.25–2.25–"Name"–"12 Main St"
;
x=1.25 y=2.25 name=Name addr=12 Main St
 
由于我暂时还没有SAS9.2系统,所以还不能测试,仅供参考。


相关博文

发表评论

电子邮件地址不会被公开。 必填项已用*标注