我想用var1计算总和。你能用两种方法进行计算吗? SQL和数据步骤使用if first.var1。
data have;
input var1 var2$ var3;
datalines;
1 a 3
1 a 4
1 a 3
2 b 5
2 b 3
3 c 1
;
run;
data want;
input var1 var2 $ var3 sum_by_var1;
datalines;
1 a 3 10
1 a 4 10
1 a 3 10
2 b 5 9
2 b 3 9
3 c 1 9
;
run;
我的两种方式:
下面的代码适用于这个小数据集,但我想知道它是否适用于大型数据集,因为很难检查结果。
proc sql;
create table new as
select
*
,sum(var3) as sum_by_var1
from have
group by var1
order by var1
;
run;
以下代码无效
data new2;
set have;
by var1;
if first.var1 then
by_var1 + var3;
run;
答案 0 :(得分:0)
这是两个完全有效的例子,用于说明如何使用分组变量执行此操作。一种方法使用SQL,第二种方法使用PROC MEANS。 在这个例子中,我正在做一个平均值,但你可以用SUM替换单词mean,得到你想要的结果。
******************************************************;
*Add average value to a dataset;
*Solution 1 - PROC MEANS + Data step;
******************************************************;
proc means data=sashelp.class noprint;
output out=avg_values mean(height)=avg_height;
run;
data class_data;
set sashelp.class;
if _n_=1 then
set avg_values;
run;
proc print data=class;
run;
*Solution 2 - PROC SQL - note the warning in the log;
PROC SQL;
Create table class_sql as
select *, mean(height) as avg_height
from sashelp.class;
quit;
******************************************************;
*Add average value to a dataset - with grouping variables;
*Solution 1 - PROC MEANS + Data step;
******************************************************;
proc means data=sashelp.class noprint nway;
class sex;
output out=avg_values mean(height)=avg_height;
run;
*sort data before merge;
proc sort data=sashelp.class out=class;
by sex;
run;
data class_data;
merge class avg_values;
by sex;
run;
proc print data=class_data;
run;
*Solution 2 - PROC SQL - note the warning in the log;
PROC SQL;
Create table class_sql as
select *, mean(height) as avg_height
from sashelp.class
group by sex;
quit;
答案 1 :(得分:0)
当使用sum运算符(+)累积时,您需要在每个组的开头将其重置为缺失。此外,由于您希望组总和与组中的每一行相关联,因此您需要在关联之前计算该总和。双DOW循环是一种常见的解决方案--DOW方法将SET
和BY
语句放在DO
循环中。在这种情况下, double 意味着有一个循环用于计算组中的统计信息,第二个循环用于输出。
data want;
* loop over all rows in group to compute the sum;
var3_sum_over_var1 = .;
do _n_ = 1 by 1 until (last.var1);
set have;
by var1;
var3_sum_over_var1 + var3;
end;
* associate var3_sum_over_var1 with each row as it is output;
do _n_ = 1 to _n_;
set have;
OUTPUT;
end;
run;
注意:DO循环开始和停止边界在循环开始时计算一次,并且在循环迭代时无法更改 - 因此do _n_ = 1 to _n_;
可以根据需要工作。
答案 2 :(得分:0)
要使用您需要使用的数据步骤修复计算:
Retain
关键字来计算var1的总和,Output
关键字只输出一次和var1的总和;到达var1的最后一次观察时,修正:
data new2;
set have;
by var1;
retain sum_by_var1;
if first.var1 then do; sum_by_var1=0; end;
sum_by_var1 + var3;
if last.var1 then do; output; end;
run;
输出:
var1=1 var2=a var3=3 sum_by_var1=10
var1=2 var2=b var3=3 sum_by_var1=8
var1=3 var2=c var3=1 sum_by_var1=1