Суммарные наблюдения SAS не в группе, по группе - PullRequest
1 голос
/ 04 марта 2020

У меня есть набор данных:

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" с сумма всех значений в столбце, кроме группы, в которой находится наблюдение.

Моя проблема заключается в том, чтобы сделать это на почти 30 миллионах наблюдений, поэтому эффективность имеет значение. Я обнаружил, что использование шага данных было более эффективным, чем использование 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;

Любая идея, как это сделать, пожалуйста?

Редактировать Я не знаю, имеет ли это значение, но приведенный мной пример - это упрощенная версия моей проблемы. В реальном случае у меня есть 2 другие групповые переменные, таким образом, беря сумму всего столбца и вычитая сумму в группе, это не является жизнеспособным решением.

Ответы [ 3 ]

3 голосов
/ 05 марта 2020

Требование

сумма всех значений в столбце, кроме группы, в которой наблюдение находится в

, указывает, что должны быть выполнены два прохода данных:

  1. Вычисляет all_sum, и каждая группа group_sum
    га sh может хранить сумму каждой группы - вычисленную с помощью указанной переменной suminc: и вызова метода .ref(). Переменная может накапливать allsum.
  2. Вычислять allsum - group_sum для каждой строки группы.
    group_sum извлекается из ha sh и вычитается из 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;
1 голос
/ 05 марта 2020

Что не так с прямым подходом? Вы должны сделать два прохода независимо от того, что вы делаете.

Вот так. Я включил дополнительные переменные, чтобы вы могли видеть, как получены значения.

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
0 голосов
/ 04 марта 2020

Я бы разбил это на два разных сегмента:

1.) Вы можете начать с использования PRO C SQL, чтобы получить суммы по группе

2.) Затем используйте некоторые операторы IF / THEN для переназначения значений по группе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...