您尝试执行的功能等效如下:
data _null_;
set issues1(rename=(issue_count=_issue_count
resolved_count=_resolved_count)) end=done;
if _n_=1 then do;
declare hash total_issues();
total_issues.defineKey("request", "area");
total_issues.defineData("request", "area", "issue_count", "resolved_count");
total_issues.defineDone();
end;
if total_issues.find() ne 0 then do;
issue_count = _issue_count;
resolved_count = _resolved_count;
end;
else do;
issue_count + _issue_count;
resolved_count + _resolved_count;
end;
total_issues.replace();
if done then total_issues.output(dataset: "issues2");
run;
此方法不需要您对数据集进行预排序。我想看看使用不同方法可以获得什么样的性能,所以我在 74M 行数据集上做了一些测试。我得到了以下运行时间(您的结果可能会有所不同):
未排序的数据集:
Proc SQL
- 12.18 秒
Data
Step With Hash Object Method(上图) - 26.68 秒
Proc Means
使用class
语句 (nway) - 5.13 秒
排序数据集(36.94 秒进行 proc 排序):
Proc SQL
- 10.82 秒
Proc Means
使用by
语句 - 9.31 秒
Proc Means
使用class
语句 (nway) - 6.07 秒
Data
Step usingby
语句(我使用了 Joe 回答中的代码) - 8.97 秒
如您所见,我不建议将数据步骤与上面显示的哈希对象方法一起使用,因为它花费的时间是 proc sql 的两倍。
我不确定为什么proc means
使用语句比使用by
语句花费更长的时间,但是我在一堆不同的数据集上尝试了这个,并看到了运行时的类似差异(我在 Linux 64 上使用 SAS 9.3)。proc means
class
需要记住的是,这些运行时对于您的情况可能完全不同,但我建议使用以下代码进行求和:
proc means data=issues1 noprint nway;
class request area;
var issue_count resolved_count;
output out=issues2(drop=_:) sum=;
run;