Dataframe SAS汇总观察值不在一组中,按组
我有一个数据集:Dataframe SAS汇总观察值不在一组中,按组,dataframe,sas,Dataframe,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万次观测中做到这一点,因此效率很重要。 我发现使用数据步骤比使用过程更有效 最终的数据库应该如下所示: data
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万次观测中做到这一点,因此效率很重要。
我发现使用数据步骤比使用过程更有效
最终的数据库应该如下所示:
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.)您可以从使用PROC SQL获取组的总和开始
2.)然后使用一些IF/Then语句按组重新分配值我将其分为两个不同的部分: 1.)您可以从使用PROC SQL获取组的总和开始 2.)然后使用一些IF/Then语句按组重新分配值 列中所有值的总和,观察值所在的组除外 指示必须进行两次数据传递:
all\u sum
和每个组的group\u sum
哈希可以存储每个组的总和——通过指定的
suminc:
变量和.ref()
方法调用计算。变量可以累加allsum
allsum
-group\u sum
。从哈希中检索
group\u 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;
要求
列中所有值的总和,观察值所在的组除外
指示必须进行两次数据传递:
all\u sum
和每个组的group\u sum
哈希可以存储每个组的总和——通过指定的
suminc:
变量和.ref()
方法调用计算。变量可以累加allsum
allsum
-group\u sum
。从哈希中检索
group\u 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
注意,作为GROUPBY子句,您拥有什么并不重要
您真的需要输出所有原始观察结果吗?为什么不直接输出汇总表呢
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
直截了当的方法有什么错?无论你做什么,你都需要两次传球 像这样。我包含了额外的变量,以便您可以看到值是如何派生的
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
注意,作为GROUPBY子句,您拥有什么并不重要
您真的需要输出所有原始观察结果吗?为什么不直接输出汇总表呢
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
关于“我发现使用数据步骤比使用过程更有效”,您尝试了什么代码?3000万行中有多少个不同的组?这不是为了这个特定的任务,我在计算大约6000万个观察值的计数变量,不记得两年前我使用的程序,因为我使用数据步骤完成了类似的任务。在我开始使用procs的时候,我花了至少2个小时才可以在不到30分钟的时间内对数据步骤做同样的事情。问题可能是RAM,计算是在RAM上只有8gb的服务器上进行的(不可能添加更多)。数据总是由
组进行预排序吗?多个分组变量如何改变您想要的?您是说在这种情况下需要多个和变量吗?关于“我发现使用数据步骤比使用过程更有效。”您尝试了什么代码?3000万行中有多少个不同的组?这不是为了这个特定的任务,我在计算大约6000万个观察值的计数变量,不记得两年前我使用的程序,因为我使用数据步骤完成了类似的任务。在我开始使用procs的时候,我花了至少2个小时才可以在不到30分钟的时间内对数据步骤做同样的事情。问题可能是RAM,计算是在RAM上只有8gb的服务器上进行的(不可能添加更多)。数据总是由组进行预排序吗?多个分组变量如何改变您想要的?你是说在这种情况下需要多个和变量吗?谢谢你的回答。它在最小的示例中非常有效,但是我在多个组中使用它时遇到了问题。在我的例子中,我有3个级别的组,第一个级别是年,然后是区域,最后是区域内的组。datastep开头的简单by语句不起作用,因为在do-while循环中,它取整个数据库的总和。您知道如何修改代码以允许更多级别的组吗?请更改defineKey
语句以列出所有组变量,sums.defineKey('byvar1','byvar2','byvar3')当然,更多的分组变量意味着更多的组合意味着需要更多的内存来保存散列。你说的是3000万次观测。你能回答以下问题吗:分组人数是多少?分组是否按顺序排列?您是否许可SAS/MDDB?Per@Tom,您是否需要一个以上的总和变量(即,您是否需要一级聚合、二级聚合和三级聚合?)是的,组已排序。第一组有9级,第二组304级,最后一组略低于100级。要记住的哈希数仅适用于最后一组,因此大约为100。对于SAS