我想要计算按另一列分组的累积最大值。
假设我有这些数据:
data have;
input grp $ number;
datalines;
a 3
b 4
a 5
b 2
a 1
b 8
;我想要的产出是:
data want;
input grp $ cummax;
a 3
b 4
a 5
b 4
a 5
b 8
;我的实际情况将涉及几个分组列+过滤器,理想情况下,这个累积最大值可以同时计算在几个列上。
我主要关注的是计算效率,因为我将在一千万到亿行的表上运行此操作。Proc SQL或本机SAS都受欢迎。
如果有必要,行可能会被洗牌。
系统信息
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
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日
发布于 2018-02-06 18:51:12
使用HASH对象存储每个变量和组组合的最大值。这将允许您对数据集进行一次遍历,并为组和变量的数量编写一些可伸缩的代码。
这不需要在大型数据集上花费昂贵的排序。
试验数据
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;计算累积最大值的数据步骤
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,我们可以对保持原始顺序的组进行排序,并查看它是否有效。(暗示,确实如此)。
proc sort data=want;
by grp: n;
run;发布于 2018-02-06 18:46:48
proc sort data=have;
by grp;
run;
data want;
set have;
by grp;
retain max;
max=ifn(first.grp,number,max(number,max));
run;使用不带排序的散列
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;发布于 2018-02-06 18:10:15
下面这样的东西会起作用的。如果您想保持原来的订单,请添加一行计数器并在其上使用:
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; https://stackoverflow.com/questions/48648946
复制相似问题