首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SAS或PROC SQL中按组分列的累积最大值

SAS或PROC SQL中按组分列的累积最大值
EN

Stack Overflow用户
提问于 2018-02-06 17:44:21
回答 4查看 883关注 0票数 2

我想要计算按另一列分组的累积最大值。

假设我有这些数据:

代码语言:javascript
复制
data have;
input grp $ number;
datalines;
a 3
b 4
a 5
b 2
a 1
b 8
;

我想要的产出是:

代码语言:javascript
复制
data want;
input grp $ cummax;
a 3
b 4
a 5
b 4
a 5
b 8
;

我的实际情况将涉及几个分组列+过滤器,理想情况下,这个累积最大值可以同时计算在几个列上。

我主要关注的是计算效率,因为我将在一千万到亿行的表上运行此操作。Proc SQL或本机SAS都受欢迎。

如果有必要,行可能会被洗牌。

系统信息

代码语言:javascript
复制
proc product_status;run;

基地SAS软件..。自定义版本信息: 9.3_M2图像版本信息: 9.03.01M2P080112用于SAS/STAT自定义版本信息: 12.1图像版本信息: 9.03.01M0P081512用于SAS/GRAPH .自定义版本信息: 9.3_M2用于SAS/CONNECT .自定义版本信息: 9.3_M2用于SAS服务器.自定义版本信息: 9.3_M1为.公司名称:上海市发布时间:北京市发布时间:上海市发布时间:2009-4-18自定义版本信息: 9.3_M2 For SAS/ACCESS Interface to Oracle .自定义版本信息: 9.3_M1的SAS/访问接口的PC文件.自定义版本信息: 9.3_M2

代码语言:javascript
复制
    proc setinit;run;

产品有效期:31 JUL2018-SAS/CONNECT 31JUL2018 -SAS OLAP服务器31JUL2018 --SAS企业Miner 31JUL2018 --MDDB Server通用产品31JUL2018 --SAS集成技术31JUL2018 --SAS企业Miner Server 31JUL2018 --SAS企业Miner客户端31 JUL2018--未使用的OLAP插槽31JUL2018 --SAS企业指南31JUL2018 -- Oracle的SAS/ACCESS接口31JUL2018 -对PC文件的SAS/ACCESS接口31JUL2018 -用于Informatica的SAS元数据桥31JUL2018 -- Microsoft SQL Server 31JUL2018的SAS元数据桥-- Oracle 31JUL2018的SAS元数据桥--用于本地访问的SAS工作区服务器31JUL2018 --用于企业访问的SAS工作区服务器31JUL2018 --SAS表服务器31JUL2018 --DataFlux Trans DB驱动程序31JUL2018 -SAS Framework Data Server 31JUL2018 - Microsoft Excel 31JUL2018的SAS外接程序-SAS外接程序用于Microsoft 31JUL2018 --用于Microsoft PowerPoint 31JUL2018的SAS外接程序--用于Microsoft的SAS外接程序2018年7月31日

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-02-06 18:51:12

使用HASH对象存储每个变量和组组合的最大值。这将允许您对数据集进行一次遍历,并为组和变量的数量编写一些可伸缩的代码。

这不需要在大型数据集上花费昂贵的排序。

试验数据

代码语言:javascript
复制
data example;
format grp1-grp5 $1.;
array grp[5];
array val[5];
do rows=1 to 1000000;
    do i=1 to 5;
        r = ceil(ranuni(1)*5);
        grp[i] = substr("ABCDE",r,1);
    end;
    do j=1 to 5;
        val[j] = 10*rannor(1);
    end;
    output;
end;
keep grp: val:;
run;

计算累积最大值的数据步骤

代码语言:javascript
复制
data want;
set example;
array val[5];
array max[5];
if _n_ = 1 then do;
    declare hash mx();
    rc = mx.defineKey('grp1','grp2','grp3','grp4','grp5');
    rc = mx.definedata('max1','max2','max3','max4','max5');
    rc = mx.definedone();
end;

rc = mx.find();
/*No Max for this combination -- add it*/
if rc then do;
    do i=1 to 5;
        max[i] = val[i];
    end;
end;

/*Update Max Values*/
do i=1 to 5;
    if val[i] > max[i] then
        max[i] = val[i];
end;

/*Update Hash*/
rc = mx.replace();

drop rc i;
n = _n_; /*This is for testing*/
run;

使用这个测试变量n,我们可以对保持原始顺序的组进行排序,并查看它是否有效。(暗示,确实如此)。

代码语言:javascript
复制
proc sort data=want;
by grp: n;
run;
票数 2
EN

Stack Overflow用户

发布于 2018-02-06 18:46:48

代码语言:javascript
复制
proc sort data=have;
by grp;
run;

data want;
   set have;
   by grp;
   retain max;
   max=ifn(first.grp,number,max(number,max));
run;

使用不带排序的散列

代码语言:javascript
复制
data want;
  if _n_=1 then do;
  declare hash h();
  h.definekey('grp');
  h.definedata('value');
  h.definedone();
  end;
  set have;
  if h.find()^=0 then do;
  h.add(key:grp,data:number);
  max=number;
  end;
  else do;
     max=max(number,value);
     h.replace(key:grp,data:number);
  end;
  drop  value number;
run;
票数 2
EN

Stack Overflow用户

发布于 2018-02-06 18:10:15

下面这样的东西会起作用的。如果您想保持原来的订单,请添加一行计数器并在其上使用:

代码语言:javascript
复制
proc sort data=have; 
by grp; 
run;

data new; 
drop newnum; 
set have;            
by grp;   
retain newnum;                                                  
if first.grp then newnum = number; 
if number > newnum then newnum=number;  
else number=newnum;
run;          
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48648946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档