Переменные SAS sum, использующие имя после транспонирования proc
У меня есть таблица с проводками по категориям (число), которые я транспонировал. Я получил таблицу с именем каждого столбца как _number, например _16, _881,_853 и т. д. (они не в порядке).
Мне нужно сделать сумму всех из них в proc sql, но я не хочу создавать переменную в шаге данных, и я также не хочу писать имена всех столбцов . Я попробовал это, но не работает:
proc sql;
select sum(_815-_16) as nnl
from craw.xxxx;
quit;
Я попробовал перейти от первого числа к последнему, а также от числа, соответствующего первое место тому, что соответствует последнему месту. Дает мне номер, который не соответствует действительности.
Есть идеи?
Спасибо!
2 ответа:
У меня нет документации, подтверждающей это, но из моего опыта я полагаю, что SAS будет предполагать, что любой оператор
Единственный способ, который я вижу для SAS, чтобы отличить их друг от друга, - это способ передачи аргументов в него. В приведенном ниже примере вы можете видеть, что внутренняя функцияsum()
в SQL является оператором SQL-aggregate, если у него нет оснований полагать иначе.sum()
имеет 3 аргумента, передаваемых в SAS, поэтому SAS будет рассматривать это как функцию SASsum()
(как 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;