子集基于标准

时间:2015-02-16 03:38:42

标签: macros sas subset

我想在每次count变量等于1时对我的数据集(使用sas)进行子集化。例如,以下数据集将分成两个数据集:

Over Ball      Bowling    Runs_scored Count 
39   1           Ali        1          1
39   2           Ali        1          2
39   3           Ali        2          3
39   4           Ali        1          4
39   5           Ali        1          5
39   6           Ali        1          6
36   1           Anderson   1          1
36   2           Anderson   1          2
36   3           Anderson   1          3
36   4           Anderson   0          4
36   6           Anderson   0          6

注意:尽管上表中的最终计数(对于每个投球手)可以被6整除,但实际(完整)数据集中并非如此。

我知道这个任务需要一个宏,但不知道从哪里开始。

谢谢, ANKIT

4 个答案:

答案 0 :(得分:0)

要分隔数据集,请在数据语句中使用两个数据集名称。并使用输出来指示输出;

data set1 set2;
    set input;
    if count = 1 then output set1;
    else output set2;
run;

因此,对每个count = 1表示添加分隔符并导出新数据集。

data test2;
    set test;
    retain n_count = 0;
    if count = 1 then n_count = n_count + 1;
run;
*calculate how many count = 1 in the dataset;
proc sql;
    select max(n_count) into :total trimmed
    from test2;
quit;

 %macro sep;
     %do i = 0 %to &total.;
        data sep_&i.;
            set test2;
            where n_count = &i.;
        run;
     %end;
  %mend;

  %sep;

答案 1 :(得分:0)

创建测试/样本数据集

data test;
infile datalines dlm=',';
input Over : 8.
      Ball : 8.
      Bowling : $15.
      Runs_scored : 8.
      Count : 8.
;
datalines; 
39,1,Ali,1,1
39,2,Ali,1,2
39,3,Ali,2,3
39,4,Ali,1,4
39,5,Ali,1,5
39,6,Ali,1,6
36,1,Anderson,1,1
36,2,Anderson,1,2
36,3,Anderson,1,3
36,4,Anderson,0,4
36,6,Anderson,0,6
;
run;

选择明显的过度(据我所知,Cricket,每个过去都会以" 1"`这就是你要找的东西)和过多的数量

proc sql noprint;
select distinct over into: overs separated by "," from test;
select count(distinct over) into :numOfOvers from test;
quit;

为每个

创建单独的数据集
%macro overnew();
 %do i=1 %to &numOfOvers.;

data over_%sysfunc(scan("&overs.",&i.,","));
set test;
where over=%sysfunc(scan("&overs.",&i.,","));
run;

%end;
%mend;

%overnew;

答案 2 :(得分:0)

另一个变体,它不使用宏,而是使用call execute。首先创建一个与@neoman相同的唯一OVERS列表,然后使用call execution来生成数据集。

data test;
infile datalines dlm=',';
input Over : 8.
      Ball : 8.
      Bowling : $15.
      Runs_scored : 8.
      Count : 8.
;
datalines; 
39,1,Ali,1,1
39,2,Ali,1,2
39,3,Ali,2,3
39,4,Ali,1,4
39,5,Ali,1,5
39,6,Ali,1,6
36,1,Anderson,1,1
36,2,Anderson,1,2
36,3,Anderson,1,3
36,4,Anderson,0,4
36,6,Anderson,0,6
;
run;

*Get all the unique overs in the list;
proc sql noprint;
create table test_unique as
select distinct over
from test
order by over;
run;

*create the call execute string to split the dataset;
data _null_;
set test_unique;

str1="data over"||put(over, z3. -l)||";";
str2=cats("set test (where=(over=",over,"));run;");
str3=cats(str1, str2);
call execute(str3);
run;

答案 3 :(得分:0)

这是一种方法,您不必多次遍历数据集。它也不使用宏,你不需要知道运行它之前有多少。

data _null_;
    set have end=done;
    if _n_=1 then do;
        declare hash h_out(ordered:"ascending");
        h_out.defineKey("count");
        h_out.defineData("over", "ball", "bowling", "runs_scored", "count");
        h_out.defineDone();
    end;

    if h_out.add() ne 0 or done then do;
        ds_count + 1;
        h_out.output(dataset: cats('want', ds_count));
        h_out.clear();
        h_out.add();
    end;
run;

这可以通过创建一个哈希对象来存储每个哈希对象,然后当它到达文件的结尾或文件末尾时,将对象写出到数据集。
第二个“if”语句尝试将行添加到哈希对象。由于我们使用“count”作为键,如果已存在重复值“count”(即count = 1),则此添加将失败。这将触发“if”语句的内部,该语句将增加数据集计数,输出到数据集,清除哈希值,并添加之前无法添加的当前行。