【问题标题】:SAS Data step Max by groupSAS Data step Max by group
【发布时间】:2018-09-29 19:41:09
【问题描述】:

我有一个数据集:

data data;
   input group $ count;
   datalines;
A 4
A 3
A 2
A 1
B 1
C 1
D 2
D 1
E 1
F 1
G 2
G 1
H 1
;
run;

第一个变量是组标识符,第二个变量按组统计观察次数,数据集按组排序,然后按计数降序排列。

我想要一个新变量,它为每个组获取最大“计数”变量,例如:

data data;
   input group $ count max_count;
   datalines;
A 4 4
A 3 4
A 2 4
A 1 4
B 1 1
C 1 1
D 2 2
D 1 2
E 1 1
F 1 1
G 2 2
G 1 2
H 1 1
;
run;

我设法得到的最接近的方法是:

data data;
    set data;
    by group;
    if first.group then max_count=count;
run;

但结果是:

data data;
   input group $ count max_count;
   datalines;
A 4 4
A 3 .
A 2 .
A 1 .
B 1 1
C 1 1
D 2 2
D 1 .
E 1 1
F 1 1
G 2 2
G 1 .
H 1 1
;
run;

您知道如何执行此操作吗?

【问题讨论】:

    标签: dataframe sas


    【解决方案1】:

    您可以使用顺序 DOW 循环进行此类处理。 DOW 循环是其中一个 SET 语句在循环内的循环——一种在介绍性 DATA 步编程中没有教授的安排。第一个循环将“测量”组以计算一些组级指标,第二个循环将在输出行时将该指标应用于组中的每个成员。

    data want;
      do _n_ = 1 by 1 until (last.group);
        set have;
        by group;
        if count > maxcount then maxcount = count;
      end;
      do _n_ = 1 to _n_;
        set have;
        output;
      end;
    run;
    

    编辑 - 更简单

    我没有仔细阅读这个问题——它说

    数据集按组排序,然后按计数降序排列。

    data want;
      set data;
      by group descending count;
      if first.group then max_count = count;
      retain max_count;
    run;
    

    解释

    接受排序条件表面上意味着最大值在组中的第一条记录处已知。因此,不需要 DOW 循环来“测量”组。

    亮点:

    • BY by 语句中的 descending count 强制执行假定条件
      • 如果计数未按预期排序,则日志中将出现错误
    • first.group 检测一组行中组值已更改的第一行。这是满足 BY 条件时计数最大的点。

      • 跟踪器变量max_count 仅在此时分配
    • retain max_count 是一个不可执行的语句。 RETAIN 告诉 DATA Step 编译器不要重置为丢失指定的非数据集变量(在隐式 DATA step 循环的顶部)。因此,在分配后,组中所有行的 max_count 不变。

    【讨论】:

    • 完美运行,感谢代码和解释,不知道这个,非常感谢!
    • 感谢第二个选项,我尝试了类似的方法,但在 by 语句中没有“递减计数”,现在我知道出了什么问题,再次感谢!
    【解决方案2】:

    数据步骤中的另一种方式,您也可以使用哈希对象。

    data want;
     if _n_ = 1 then do;
     dcl hash h(multidata:"Y", dataset:"data");
     h.definekey("group");
     h.definedone();
     end;
     set data ;
     by group;
      if  h.find() = 0 then do until(h.find_next() ne 0);
     max_count=sum(max_count,1);
      end;
     run;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-01
      • 2010-11-20
      • 2012-10-30
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多