我有一个包含50行的表格。我想取整个表的每个数字列的平均值,最近的40行和最近的30行。行具有日期标识符,该标识符从底部的最旧到最新递减。
有没有人知道如何用proc mean或proc sql做到这一点?
答案 0 :(得分:1)
您可以使用数据步骤视图和第一个数据集选项创建分析组。
data analysis;
set sashelp.class(in=in1) sashelp.class(in=in2 firstobs=6) sashelp.class(in=in3 firstobs=12);
select;
when(in1) group=1;
when(in2) group=2;
when(in3) group=3;
end;
run;
proc means;
class group;
run;
答案 1 :(得分:0)
考虑proc sql
一个派生表,该表运行外部查询的条件平均计算中使用的相关计数子查询。下面运行三个数字列,将其扩展为适合实际数据集:
proc sql;
CREATE NewDataSet AS
(SELECT Avg(main.NumCol1) As FullAvgNumCol1, Avg(main.NumCol2) As FullAvgNumCol2,
Avg(main.NumCol3) As FullAvgNumCol3,
Avg(CASE WHEN main.RowCount <= 40
THEN main.NumCol1 ELSE NULL END) AS Top40AvgNumCol1,
Avg(CASE WHEN main.RowCount <= 40
THEN main.NumCol2 ELSE NULL END) AS Top40AvgNumCol2,
Avg(CASE WHEN main.RowCount <= 40
THEN main.NumCol3 ELSE NULL END) AS Top40AvgNumCol3,
Avg(CASE WHEN main.RowCount >= main.FullCount - 30
THEN main.NumCol1 ELSE NULL END) AS Bottom30AvgNumCol1,
Avg(CASE WHEN main.RowCount >= main.FullCount - 30
THEN main.NumCol2 ELSE NULL END) AS Bottom30AvgNumCol2,
Avg(CASE WHEN main.RowCount >= main.FullCount - 30
THEN main.NumCol3 ELSE NULL END) AS Bottom30AvgNumCol3
FROM
(SELECT sub.NumCol1, sub.NumCol2, sub.NumCol3,
(SELECT Count(*) FROM DataSet sub
WHERE sub.Date <= d.Date) As RowCount,
(SELECT Count(*) FROM DataSet) As FullCount
FROM DataSet d) AS main);
quit;
答案 2 :(得分:0)
希望这是一个简单的替代方案。由于您的数据已经订购,您可以创建一个日期计数器,该计数器从最近一天算起,然后在过程中使用where语句。
创建一些玩具数据 - 随机日期和3个数字列。
data one;
do i = 1 to 50;
date = 20000+i;
num1 = rand("Poisson", 6);
num2 = rand("uniform");
num3 = i*(i-1);
output;
end;
format date date9.;
drop i;
run;
创建由proc表示的计数器。 最近一天的价值为1,那么最早的一天的价值为50。
data two;
set one nobs= nobs;
datecount = nobs - _N_ + 1;
run;
在proc中使用where语句 - datecount =&lt; 30说你想要最近30天。
proc means data = two ( where = ( datecount =< 30));
var num1 num2 num3;
output out = averages (drop = _type_ _freq_)
mean = Mean1 Mean2 Mean3;
run;