SAS, сумма по группам - PullRequest
       10

SAS, сумма по группам

0 голосов
/ 26 апреля 2018

Я хочу рассчитать сумму по 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 голосов
/ 26 апреля 2018

Когда оператор суммирования (+) используется для накопления, вам нужно будет сбросить его на пропущенный в начале каждой группы.Кроме того, поскольку вы хотите, чтобы групповая сумма была связана с каждой строкой в ​​группе, вам необходимо вычислить эту сумму перед ее ассоциированием.Двойной цикл 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_; работает как нужно.

0 голосов
/ 26 апреля 2018

Чтобы исправить ваш расчет с помощью шага данных, вам нужно использовать:

  1. Retain ключевое слово для вычисления суммы по var1,
  2. Output ключевое слово для вывода только один развычисляется сумма по var1;это достигается при достижении последнего наблюдения для var1,
  3. Если вы хотите, чтобы сегрегированные данные вам приходилось возвращать в свою таблицу Have.

Исправление:

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 
0 голосов
/ 26 апреля 2018

Вот два полностью проработанных примера, которые иллюстрируют, как это сделать с помощью переменной группировки.Один метод использует SQL, а второй - PROC MEANS.В этом примере я делаю среднее значение, но вы можете заменить слово среднее на SUM и получить желаемый результат.

******************************************************;
*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;
...