Переменные SAS sum, использующие имя после транспонирования proc


У меня есть таблица с проводками по категориям (число), которые я транспонировал. Я получил таблицу с именем каждого столбца как _number, например _16, _881,_853 и т. д. (они не в порядке).

Мне нужно сделать сумму всех из них в proc sql, но я не хочу создавать переменную в шаге данных, и я также не хочу писать имена всех столбцов . Я попробовал это, но не работает:

proc sql;
select sum(_815-_16) as nnl
from craw.xxxx;
quit;

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

Есть идеи?

Спасибо!

2 3

2 ответа:

У меня нет документации, подтверждающей это, но из моего опыта я полагаю, что SAS будет предполагать, что любой оператор sum() в SQL является оператором SQL-aggregate, если у него нет оснований полагать иначе.

Единственный способ, который я вижу для SAS, чтобы отличить их друг от друга, - это способ передачи аргументов в него. В приведенном ниже примере вы можете видеть, что внутренняя функция sum() имеет 3 аргумента, передаваемых в SAS, поэтому SAS будет рассматривать это как функцию SAS sum() (как sql-aggregate оператор допускает только один аргумент). Затем результат функции SAS передается в качестве единственного параметра функции SQL-aggregate sum:
proc sql noprint;
  create table test as 
  select sex,
         sum(sum(height,weight,0)) as sum_height_and_weight
  from sashelp.class
  group by 1
  ;
quit;

Результат:

proc print data=test;
run;

              sum_height_
Obs    Sex     and_weight

 1      F        1356.3
 2      M        1728.6

Также обратите внимание на трюк, который я использовал в коде, передав 0 в функцию SAS - это простой способ добавить дополнительный параметр без изменения предполагаемого результата. В зависимости от ваших данных, вы можете поменять 0 на нулевое значение (т. е. .).

EDIT: To решите проблему неизвестных имен столбцов, вы можете создать макросовую переменную, содержащую список имен столбцов, которые вы хотите суммировать вместе:

proc sql noprint;
  select name into :varlist separated by ',' 
  from sashelp.vcolumn 
  where libname='SASHELP'
    and memname='CLASS'
    and upcase(name) like '%T'  /* MATCHES HEIGHT AND WEIGHT */
    ;
quit;

%put &varlist;

Результат:

Height,Weight

Обратите внимание, что вам нужно будет изменить вышеупомянутый подстановочный знак, чтобы он соответствовал вашему сценарию - т. е. сопоставление полей, которые начинаются с подчеркивания, вместо полей, которые заканчиваются буквой T. таким образом, ваш окончательный оператор SQL будет выглядеть примерно так:

proc sql noprint;
  create table test as 
  select sex,
         sum(sum(&varlist,0)) as sum_of_fields_ending_with_t
  from sashelp.class
  group by 1
  ;
quit;
Это дает альтернативный подход к ответу Джо. - хотя я считаю, что использование вида, как он предлагает, - более чистый путь.

Вы не можете использовать списки переменных в SQL, поэтому _: и var1-var6 и var1--var8 не работают.

Самый простой способ сделать это-представление шага данных.

proc sort data=sashelp.class out=class;
 by sex;
run;
*Make transposed dataset with similar looking names;
proc transpose data=class out=transposed;
 by sex;
 id height;
 var height;
run;
*Make view;
data transpose_forsql/view=transpose_forsql;
 set transposed;
 sumvar = sum(of _:);  *I confirmed this does not include _N_ for some reason - not sure why!;
run;

proc sql;
 select sum(sumvar) from transpose_Forsql;
quit;