SAS:计算平均值的向后看数据步骤

SAS:计算平均值的向后看数据步骤,sas,Sas,很抱歉,这篇文章的标题“不是很有用”。 我在SAS中设置了以下数据: time Add time_delete 5 3.00 5 5 3.15 11 5 3.11 11 8 4.21 8 8 3.42 8 8 4.20 11 11 3.12 . 其中,时间对应于拍卖中每3分钟新增加的(添加)价格。此价格可以在相同的时间间隔内或更高的时间间隔内删除,如time\u delete所示。我的目标是从每个时间的Add字段计算平均

很抱歉,这篇文章的标题“不是很有用”。 我在SAS中设置了以下数据:

time Add    time_delete
5    3.00   5
5    3.15   11
5    3.11   11
8    4.21   8
8    3.42   8
8    4.20   11
11   3.12   .
其中,
时间
对应于拍卖中每3分钟新增加的(
添加
)价格。此价格可以在相同的时间间隔内或更高的时间间隔内删除,如
time\u delete
所示。我的目标是从每个
时间的
Add
字段计算平均价格。例如,我在
time=5
时的平均价格是
(3.15+3.11)/2
,因为
3.00
在间隔内被删除。那么
时间=8时的平均价格为
(4.20+3.15+3.11)/3
。正如你所看到的,我必须看看我现在所处的时间,回头看看在
time=8
时哪个价格仍然有效。另外,我希望有一个字段,在该字段中,对于每一次
时间
我都知道未删除的最高可用价格。
有什么帮助吗

这里有一个滚动和的变体。没有一个简单的解决方案(特别是当你毫无疑问有一些未提及的复杂问题时);但这里有一些建议

首先,您可能需要更改数据的格式。如果每个可能的时间点有一行,而不是只有一行,那么这实际上是一个相对容易解决的问题

data have;
input time Add    time_delete;
datalines;
5    3.00   5
5    3.15   11
5    3.11   11
8    4.21   8
8    3.42   8
8    4.20   11
11   3.12   .
;;;;
run;

data want;
set have;
if time=time_delete then delete;
else do time=time to time_delete-1;
  output;
end;
keep time add;
run;

proc means data=want mean max n;
class time;
var add;
run;
您可以将proc means输出到数据集,并将最大值加上平均值,然后将其放回主数据集或任何您需要的数据集

这样做的主要缺点是它的数据集要大得多,因此,如果您要查看数十万个数据点,那么这可能不是您的最佳选择

您也可以在SQL中执行此操作,而不需要额外的行,尽管这是那些“其他复杂因素”可能带来麻烦的地方

proc sql;
select H.time, mean(V.add), max(V.add) from (
    select distinct H.time from have H
    left join
    (select * from have) V
    on V.time le H.time
    and V.time_delete gt H.time )
    group by 1;
;
quit;
相当直接和快速的查询,只是如果您有很多时间值,那么执行连接可能需要一些时间

其他选择:

  • 将数据读入一个数组,第二个数组跟踪删除点。这可能会变得有点复杂,因为您可能需要按删除点对数组进行排序-因此,您需要向下移动一组记录,而不仅仅是在末尾添加一条新记录。SAS对于这种操作不像c型语言那样友好

  • 使用哈希表解决方案。比数组稍微简单一些,特别是因为您可以比两个单独的数组更轻松地对哈希表进行排序

  • 使用IML和向量。与阵列解决方案类似,但具有更强大的操作技术


谢谢您的帮助!但是对于第二段代码的第二部分,我收到了这样一条消息:“无效的DO循环控制信息,要么缺少初始或TO表达式,要么缺少BY表达式,要么为零,要么无效。”有什么建议吗?要么输入错误,要么运行的不完全是SAS(WPS/等)。这个例子在我的机器上运行得很好,关于DO循环的任何内容都不是版本特定的。但是,尽管有错误消息,我仍然得到了所需的输出!在执行
if and else
步骤之前,我应该为每个“时间组”创建一个唯一的时间id。比如数据需要<代码>按时间;如果为first.time,则为time_id+1;运行
并使用我的新时间id在第二组代码行(time to time_delete)上执行,这样我就不必担心创建“不需要的”行了。您介意格式化您的问题以使其更具可读性吗?