我有一个表格,按类别(数字)发布我转置的内容。我得到一个表,每个列的名称为_number,例如_16,_881,_853等(它们不按顺序排列)。
我需要在proc sql中完成所有这些操作的总和,但我不想在数据步骤中创建变量,而且我不想写所有的列名或者。我尝试了这个但是没有工作:
proc sql;
select sum(_815-_16) as nnl
from craw.xxxx;
quit;
我尝试将第一个数字转到最后一个,也从第一个地方的数字到最后一个地方的数字。给我一个不正确的数字。
有什么想法吗?
谢谢!
答案 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的回答提供了另一种方法 - 尽管我认为使用该视图是他认为更清洁的方式。