2015-09-25 102 views
0

我使用SAS来的数据集分成具有以下命名约定的子集:sub001,sub002,sub003 ....我的数据集看起来像SAS:如何将数据按顺序拆分为名称的子集。

ID var1 
AA ... 
AA ... 
AB ... 
AC ... 
... ... 
AZ ... 
... ... 
ZZ ... 

我可以手动执行此操作。

data sub001 sub002.....sub676; 
set data; 
if id='AA' then output sub001; 
..... 
if id='ZZ' then output sub676; 
run; 

但是有没有简单的方法可以做到这一点?我认为%macro%do可以在这里帮助。

+1

请显示你已经尝试过。另外,你确定你想要这样做吗?像这样分割数据通常是一个低效率的解决方案。如果你描述你为什么要分割数据,人们可能会给你更好的选择。 – Quentin

+2

ID的每个值是否成为其自己的子集?如果是这样,为什么不在以后的分析中使用BY ID语句而不是制作许多小数据集? – Tom

回答

0

如果您正在寻找将它们全部分割成一堆数据集,可以使用宏来完成。这是中宏编程我最喜欢的小动作之一:

第1步:阅读所有不同的ID添加到一个空格分隔的宏变量

proc sql noprint; 
    select distinct strip(upcase(id)) 
    into :all_ids separated by ' ' 
    from have; 
quit; 

步骤2:循环在总的话中&all_ids上的& all_ids

options nonotes; 

%macro split; 
    %do i = 1 %to %sysfunc(countw(&all_ids)); 
     data sub_&i; 
      set have; 
      where upcase(ID) = "%scan(&all_ids, &i)"; 
     run; 
    %end; 
%mend; 
%split; 

options notes; 

每个值过滤have因为我们循环在托特空格分隔的宏变量&all_ids中的单词数目在&i的值与每个单词的位置在&all_ids之间存在1-1对应关系。例如:

&i |  &all_ids  
LOOP WORD NUMBER  WORD   
1   1    AA 
2   2    AB 
3   3    AC 

这是不这样做,因为我们每次写入新的数据集到磁盘的最有效方法,但除非你的资源是非常有限的,或者你有数以百计一个可怕的数据集和数百GB或更多,它应该很快完成。如果您需要一种方式来减少I/O,我也可以帮助您。