Sas 这个多步骤的过程可以简化为一个proc-sql语句吗?
我一直在努力使我的代码更高效,这是原始代码,但我认为它可以一步编写完成Sas 这个多步骤的过程可以简化为一个proc-sql语句吗?,sas,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 nopri
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;
我不得不编辑一些代码,但我认为总体思路应该是合理的。
主要问题是我无法调用多列,因为它刚刚创建,但我想为每种类型创建一个百分比。执行类似操作的“SAS”方法是使用CLASS
语句和PROC MEANS
。这将计算数据中所有交互级别的统计信息(由类型变量标识)。TYPE=0的行将是“总计”值,表示整个数据集的统计值
在您的情况下,我们可以利用以下事实:PROC意味着
将创建按类型和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意思的语句非常有用。花几分钟阅读类型变量是如何计算的,特别是当您尝试使用多个类变量时。这样做的“SAS”方法是使用class
语句和PROC MEANS
。这将计算数据中所有交互级别的统计信息(由类型变量标识)。TYPE=0的行将是“总计”值,表示整个数据集的统计值
在您的情况下,我们可以利用以下事实:PROC意味着
将创建按类型和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意思的语句非常有用。花几分钟阅读类型变量的计算方法,特别是如果您尝试使用多个类变量。您可以通过使用PROC MEANS的VAR语句中的WEIGHT选项跳过初始数据步骤(这将有效地为您进行乘法运算)。您还可以使用PROC TABLATE而不是PROC MEANS,因为TABLATE可以计算百分比。我相信下面的代码将一次性生成所需的输出
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;
您可以使用PROC MEANS的VAR语句中的WEIGHT选项跳过初始数据步骤(这将有效地为您执行乘法)。您还可以使用PROC TABLATE而不是PROC MEANS,因为TABLATE可以计算百分比。我相信下面的代码将一次性生成所需的输出
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;
如果您需要一个步骤,这可能会起作用,但实际上效率不高,因为它会处理两次数据,一次按类型处理细节,一次按总数处理
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;
为了提高效率,您可以通过多个步骤在原始代码中用E视图替换表:
数据表代码>=>数据表/视图=表代码>
create table table 4
=>create view table 4
如果您需要一个步骤,这可能会奏效,但实际上效率不高,因为它会处理两次数据,一次按类型处理细节,一次按总数处理
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;
为了提高效率,您可以通过多个步骤在原始代码中用E视图替换表:
数据表代码>=>数据表/视图=表代码>
创建表4
=>创建视图表4