数据清洗DATA CLEARING之infile选项之六 与INPUT控制符号联用

碰到这样的一个源数据需要读入:
000001 p1,p2,p3
000002 p2,p3
500003 p5,p6
080004 p2,p7
008005 p3,p4,p1,p2
000006 p4,p5,p6
009007 p2,p9
000408 p10
 
目标数据集为:
000001    p1
000001    p2
000001    p3
000002    p2
000002    p3
500003    p5
500003    p6
080004    p2
080004    p7
008005    p3
008005    p4
008005    p1
008005    p2
000006    p4
000006    p5
000006    p6
009007    p2
009007    p9
000408    p10
 
源数据看起来非常的有规律,需要后一个变量对应的字段扯开。这时候会有许多的小技巧方法,有如下几种思想:
1,把后面的全部当一个字段读入到一个变量,然后一个一个拆开(用函数),然后拼成。
2,用x1-xn,把后面全部读入,没有的设置成缺失(后面再T掉),然后用数组和循环的方法修正为要求的数据集格式。
3,用矩阵分组转制,然后merge。
 
上面的两种思想都可以用代码来实现目的,但是代码是非常的不简洁,并且性能和通用性也不好。
其实SAS提供了一种可以说是专门解决这类问题的方法(在SAS公司培训资料上看过的,BASE的内容)。
data Ex;
infile cards missover dlm=’,’;
input Code $6. Per $ @;
do while (Per ne ”);
output;
input Per $ @;
end;
cards;
000001 p1,p2,p3
000002 p2,p3
500003 p5,p6
080004 p2,p7
008005 p3,p4,p1,p2
000006 p4,p5,p6
009007 p2,p9
000408 p10
;
run;
 
在之前,遇到一个类似例子,也是用同样的方法解决:
data ex  ;
  infile datalines missover;
   input status  family member@;
     do while (member ne .) ;
  output;
  input member @;
  end;
datalines;
9 1 3809 3810 3811 3812
9 2 3814 3815 3816
1 3 3817 3818 3819 3820
;
 
还有一个更一般的例子,这个可能是实际中遇到真实的情况。
 
001 A 头疼 轻度 感冒 重度 ALT增高 轻度
002 B 咳嗽 轻度 过敏 轻度
003 B 感冒 轻度
004 A 感染 中度
 
实现代码是:
data ex  ;
  infile datalines missover;
   input drug group  $ res $ chdu $ @;
     do while (res ne ”) ;
  output;
  input res $ chdu $ @;
  end;
datalines;
001 A 头疼 轻度 感冒 重度 ALT增高 轻度
002 B 咳嗽 轻度 过敏 轻度
003 B 感冒 轻度
004 A 感染 中度
;
run;
 
 
结合infile的选择和行读入控制符号@(input pointer),就可以很好的解决这个问题,并且是一种通用的方法。(前面有一个列控制符号#与infile选项联用的例子:数据清洗DATA CLEARING之infile选项之四 N OBS FIRSTOBS)。
 
小结:
1,SAS提供了非常灵活的数据接口,input就是其中技术之一。infile的选项和input的各种控制符号结合,使得SAS与外界的数据接口变得很灵活很强大。其实input本身读入数据过程是一个步骤非常多的一个过程,并且SAS提供了好多的方法对其各阶段进行控制。有机会偷窥一下SAS的input机制。
2,SAS9以后提供的HASH对象方法,也可以解决这个问题,以后补充。
 

相关博文

发表评论

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