在proc转置后使用名称对SAS求变量

时间:2014-07-28 15:01:16

标签: sas transpose summarization

我有一个表格,按类别(数字)发布我转置的内容。我得到一个表,每个列的名称为_number,例如_16,_881,_853等(它们不按顺序排列)。

我需要在proc sql中完成所有这些操作的总和,但我不想在数据步骤中创建变量,而且我不想写所有的列名或者。我尝试了这个但是没有工作:

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

我尝试将第一个数字转到最后一个,也从第一个地方的数字到最后一个地方的数字。给我一个不正确的数字。

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

您无法在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;

答案 1 :(得分:1)

我没有文档可以支持这一点,但根据我的经验,我相信SAS会假设SQL中的任何sum()语句都是sql-aggregate语句,除非它有理由相信。

我能看到SAS区分二者的唯一方法是通过参数传递给它。在下面的示例中,您可以看到内部sum()函数传入了3个参数,因此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替换为空值(即.)。

编辑:要解决未知列名称的问题,您可以创建一个宏变量,其中包含要一起求和的列名列表:

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;

这为Joe的回答提供了另一种方法 - 尽管我认为使用该视图是他认为更清洁的方式。