SAS对不分组的观察结果进行汇总



我有一个数据集:

data have;
input group $ value;
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;

第一个变量是组标识符,第二个变量是值。

对于每组,我想要一个新的变量"sum",其中包含列中所有值的总和,除了观察所在的组。

我的问题是必须在近3000万次观测中做到这一点,所以效率很重要。我发现使用数据步骤比使用procs更有效。

最终的数据库应该是这样的:

data want;
input group $ value $ sum;
datalines;
A 4 11
A 3 11
A 2 11
A 1 11
B 1 20
C 1 20
D 2 18
D 1 18
E 1 20
F 1 20
G 2 18
G 1 20
H 1 20
;
run;

你知道怎么表演吗?

编辑:我不知道这件事是不是,但我举的例子是我问题的简化版本。在实际情况下,我有另外两个群变量,因此取整列的和减去群中的和是不可行的。

要求

列中所有值的总和,除了观察在中的组

表示必须进行两次数据传递:

  1. 计算all_sum和每个组的group_sum
    哈希可以存储每个组的和——通过指定的suminc:变量和.ref()方法调用计算。一个变量可以累加allsum
  2. 为一组中的每一行计算allsum-group_sum
    从散列中检索group_sum,并从allsum中减去

示例:

data want;
if 0 then set have; * prep pdv;
declare hash sums (suminc:'value');
sums.defineKey('group');
sums.defineDone();
do while (not hash_loaded);
set have end=hash_loaded;
sums.ref();                * adds value to internal sum of hash data record;
allsum + value;
end;
do while (not last_have);
set have end=last_have;
sums.sum(sum:sum);         * retrieve groups sum. Do you hear the Dragnet theme too?;
sum = allsum - sum;        * subtract from allsum;
output;
end;
stop;
run;

直接方法有什么问题?无论你做什么,你都需要两次传球。

就像这样。我包含了额外的变量,这样你就可以看到这些值是如何导出的。

proc sql ;
create table want as
select a.*,b.grand,sum(value) as total, b.grand - sum(value) as sum
from have a
, (select sum(value) as grand from have) b
group by a.group
;
quit;

结果:

Obs    group    value    grand    total    sum
1      A        3        21       10      11
2      A        1        21       10      11
3      A        2        21       10      11
4      A        4        21       10      11
5      B        1        21        1      20
6      C        1        21        1      20
7      D        2        21        3      18
8      D        1        21        3      18
9      E        1        21        1      20
10      F        1        21        1      20
11      G        1        21        3      18
12      G        2        21        3      18
13      H        1        21        1      20

请注意,GROUP BY子句中包含的内容并不重要。

你真的需要输出所有的原始观测结果吗?为什么不直接输出汇总表呢?

proc sql ;
create table want as
select a.group, b.grand - sum(value) as sum
from have a
, (select sum(value) as grand from have) b
group by a.group
;
quit;

结果

Obs    group    total    sum
1       A        10      11
2       B         1      20
3       C         1      20
4       D         3      18
5       E         1      20
6       F         1      20
7       G         3      18
8       H         1      20

我将把它分成两个不同的部分:

1.(您可以从使用PROC SQL开始,按组获取总和

2.(然后使用一些IF/Then语句按组重新分配值

最新更新