SAS:将聚合数据添加到同一数据集

BoT*_*oTz 0 sas

我正在从 SPSS 迁移到 SAS。我需要分别按变量varA varB计算变量 varX 的总和,并将其作为新变量sumX添加到同一数据集。

在 SPSS 中,这可以通过aggregate轻松实现:

aggregate outfile *
/break varA varB
/SUMvarX = sum(varX).
Run Code Online (Sandbox Code Playgroud)

这可以在 SAS 中完成吗?

Joe*_*Joe 5

有多种方法可以做到这一点,但最好的方法取决于您的数据。

对于典型的用例,PROC MEANS我推荐的解决方案是。它不是最快的,但它可以完成工作,并且出错的机会要低得多 - 除了之后的匹配合并之外,您实际上并没有做任何事情。

大多数情况下使用class语句代替;by它应该不会有太大区别,但这是 的目的classby对这些变量的每个值分别运行分析;class按所有这些变量运行一项分析分组。它更灵活,不需要排序的数据集(尽管您必须为以后的合并进行排序)。 class还可以让您进行多种组合 - 不仅仅是nway您在这里要求的组合,而且如果您希望它仅按a、仅按b和 按分组a*b,您可以得到它(使用classtypes)。

proc means data=have;
  class a b;
  var x;
  output out=summary sum(x)=;
run;

data want;
  merge have summary;
  by a b;
run;
Run Code Online (Sandbox Code Playgroud)

Kermit 的答案中涵盖的 DoW 循环也是一个合理的数据步骤选项,尽管在程序员错误方面风险更大;我只会在数据集非常非常大的特定情况下使用它 - 超出了内存的摘要大小- 并且性能很重要。

如果数据适合内存,您还可以使用哈希表进行摘要,如果摘要数据集适合内存,我就会这样做。对于这里的答案来说太长了,但是使用哈希对象进行数据聚合是如何做到这一点的一个很好的开始。基本上,您使用哈希表来存储摘要结果(而不是原始数据),将每一行添加到它,然后在最后输出哈希表。比 DoW 循环快一点,但内存略有限制(尽管如果您使用 SPSS,则内存限制比这要多得多!)。也很容易处理多种组合。

另一种“程序员简单”的方法是使用 SQL。

proc sql;
  create want as
   select *, sum(x) as sum_x
    from have
    group by a,b
  ;
quit;
Run Code Online (Sandbox Code Playgroud)

这不是标准 SQL,但 SAS 管理它 - 基本上它一步完成了合并proc means和合并的两步过程。我在某些方面喜欢这个(因为它跳过了中间数据集,即使它实际上在 util 文件夹中创建了这个数据集,只是自动为您清理)并且不喜欢它在其他方面(它不是标准 SQL,所以它会让人们感到困惑,它会在日志中留下一条注释 - 只是一条注释,所以没什么大不了的,但仍然如此)。


添加关于 SPSS -> SAS 思维的注释。从 SPSS 到 SAS 的最大区别之一是,在 SPSS 中,您有一个数据集,并且您可以对其进行操作(大部分)。您可以将其另存为不同的数据集,但大多数情况下直到最后才会这样做 - 您的所有工作实际上只是在内存中编辑一个数据集。

在 SAS 中,您从磁盘读取数据集并执行一些操作,然后将它们写出来,如果您正在数据集级别执行任何操作(例如摘要),您通常会单独执行此操作,然后与数据重新组合在一个稍后的步骤。因此,拥有大量数据集是非常非常常见的——我刚刚运行的程序可能有一千个。不开玩笑!不要担心生成随机临时数据集 - 这并不意味着您的代码效率不高。这就是 SAS 的工作原理。有时你确实必须小心 - 比如你有 150GB 的数据集或其他东西 - 但如果你正在处理 5000 行和 150 个变量,你的数据集是如此之小,你可以将它写入一千次而不会注意到有意义的与您的代码执行时间的差异。

这种风格的一大好处是,每个步骤都有不同的数据集,因此,如果您返回并想要重新运行部分代码,您可以安全地知道前一个数据集仍然存在,而不必重新运行所有代码。它还可以让您非常轻松地进行调试,因为您可以看到每个组件。

这肯定是一种权衡,因为这确实意味着运行代码需要更长的时间,但在现代,CPU 真的非常快,SSD 也是如此 - 只是没有必要编写将所有数据保留在一个数据步骤中的代码或者完全在内存中运行。权衡是,你有能力做大量内存无法容纳的疯狂事情,处理大量数据集等等——仅受磁盘的限制,而磁盘的供应量通常要大得多。在许多情况下,这是值得做出的权衡。当可以在 PROC 中执行某些操作时,请执行此操作,即使这意味着最终需要花费一点时间来重新合并它 - PROC 就是您为 SAS 支付大笔费用的原因,它们很容易使用,经过充分测试,并且快速完成他们所做的事情。