这个多步骤过程可以简化为一个proc sql语句吗?

时间:2013-06-26 20:30:31

标签: sas

我一直在尝试提高代码效率,这是原始代码,但我认为可以一步编写。

data TABLE;set ORIGINAL_DATA;
Multi=percent*total_units;
keep Multi Type;
proc sort; by Type;
proc means noprint data=TABLE1; by Type; var Multi;output out=Table2(drop= _type_ _freq_)sum=Multi;run;
proc means noprint data=Table1;  var Multi;output out=Table3(drop= _type_ _freq_) sum=total ;run;

proc sql;
    create table TABLE4as 
    select a.Type, a.Multi label="Multi", b.total label="total"
    from TABLE2 a, TABLE3 b
    order by Type;
quit;

data TABLE5;set TABLE4;
pct=(MULTI/total)*100;
run;

我能够将其中的一部分拆分,但我无法弄清楚如何在我的代码中获得PCT部分。这就是我所拥有的。

proc sql;
create table TABLE1 as
select distinct type, sum(percent*total_units) as MULTI label "MULTI", 
    MULTI/(percent*total_units)) as PCT
from ORIGINAL_DATA
group by type;
quit;

我不得不编辑一些代码,但我认为一般的想法应该有意义。 主要问题是我无法调用MULTI列,因为它只是被创建但我想为每种类型创建总数的百分比。

3 个答案:

答案 0 :(得分:4)

执行此类操作的“SAS”方法是使用CLASS语句PROC MEANS。这将计算数据中所有交互级别的统计信息(由 TYPE 变量标识)。 TYPE = 0的行将是“total”值,表示整个数据集的统计值。

在您的情况下,我们可以利用PROC MEANS将创建按 TYPE 排序的输出数据集以及CLASS语句中列出的变量这一事实。这意味着我们可以只读取第一个观察值并保存它用于计算百分比的值。

显示一些代码可能更容易:

data TABLE;
   set ORIGINAL_DATA;
   Multi = percent * total_units;
   keep Multi Type;
run;

proc means noprint data=TABLE;
   class Type;
   var multi;
   output out=next sum=;
run;

data want;
   retain total;
   set next;
   if _n_ = 1 then do;
      /* The first obs will be the _TYPE_=0 record */
      total = multi;
      delete;
      end;
   pct = (multi / total) * 100;
   drop total _freq_ _type_;
run;

请注意,在使用PROC MEANS之前,您无需对数据进行排序。那是因为我们使用CLASS语句而不是BY语句。数据步骤使用由MEANS TYPE = 0记录)创建的数据集中的第一个观察值来保留变量的总和。 delete语句将其保留在结果之外。

使用CLASS

PROC MEANS语句非常有用。花几分钟时间阅读如何计算 TYPE 变量,特别是如果您尝试使用多个类变量。

答案 1 :(得分:3)

您可以使用PROC MEANS的VAR语句中的WEIGHT选项跳过初始数据步骤(这将有效地为您进行乘法)。您也可以使用PROC TABULATE而不是PROC MEANS,因为制表可以计算百分比。我相信以下代码将一次性生成您所需的输出。

ods noresults;
proc tabulate data=have out=want (drop=_: rename=(total_units_sum=total total_units_pctsum_0=pct));
class type;
var total_units / weight=percent;
table type, total_units*(sum pctsum);
run;
ods results;  

答案 2 :(得分:1)

如果你需要一个步骤,也许这会有效,但它实际上并不高效,因为它处理数据两次,一次是TYPE的细节,一次是总计。

proc sql;
create table TABLE1 as
select 
d.type
, sum(d.percent*d.total_units) as MULTI label "MULTI"
, calculated MULTI/s.total as PCT
from ORIGINAL_DATA d,
 ( select sum(percent*total_units) as total 
from ORIGINAL_DATA) s
group by type
;
quit;

为了提高效率,您可以通过多个步骤将原始代码中的视图替换为表格:

data TABLE; => data TABLE / view=TABLE;

create table TABLE4 => create view TABLE4