SAS,按组分类

时间:2018-04-25 22:38:58

标签: sas

我想用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;

3 个答案:

答案 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方法将SETBY语句放在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)

要使用您需要使用的数据步骤修复计算:

  1. Retain关键字来计算var1的总和,
  2. Output关键字只输出一次和var1的总和;到达var1的最后一次观察时,
  3. 如果您需要隔离的数据,则必须加入您的Have表。
  4. 修正:

    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