0

我的数据按ID日期排序。我已将日期转换为具有排序的单个数字(年份,然后是一年中的一周)。我想创建一个新变量,它是最好分区中最小值的函数。示例如下

ID  Start   listen

1   201134   201138

1  201204  201150

2  200905   200910

2  201005   201020

我想要类似的东西

ID 开始听 weekSincestart

1   201134   201138  4

1  201204  201150   54

2  200905   200910  5

2  201005   201020  15

我所做的只是采取(listen-min(start)),但我假设min()正在采取给定的最小开始ID。所以,我在问 min 函数是否有“by statement”

4

3 回答 3

1

在我看来,没有必要使用您拥有的方法从日期转换您的开始和收听值。

我使用 INTNX 在 START 和 LISTEN 变量中使用一年中的第一天将您的数据转换回日期,并在相同变量中按周递增。日期可能与您在数据集上的日期不完全相同,但它应该会产生类似的结果。

如果我理解正确,以下应该做你想做的事。

DATA WANT2;
    SET HAVE;
    BY ID START;
    RETAIN _START;
    FORMAT _START DATE9.;
    IF FIRST.ID THEN _START = START;
    WEEKSINCESTART = INTCK("WEEK",_START,LISTEN);
RUN;

在这种情况下,您的样本已排序,但是如果您希望通过语句处理来识别 ID 中值的第一个实例,则需要首先对数据集进行排序。保留语句将保存一个值,通过使用 by 语句,我们可以指定保留变量中的值何时更改。在这种情况下,我们希望在遇到第一个 ID 实例时更改 _START 变量。我使用下划线前缀,因为如果需要,它可以更容易地删除这些变量。在 ID 的下一个实例之前,该值不会被替换,这意味着它将是 ID 1 的后续观察值,依此类推。INTCK 函数测量间隔的数量,在本例中是周期数,在周期一和周期二之间,

最终结果是:

ID START     LISTEN    _START    WEEKSINCESTART
1  21AUG2011 18SEP2011 21AUG2011 4
1  29JAN2012 11DEC2011 21AUG2011 16
2  01FEB2009 08MAR2009 01FEB2009 5
2  31JAN2010 16MAY2010 01FEB2009 67  

我希望这很有用。

问候,斯科特

于 2013-08-05T05:58:24.093 回答
0

您可以使用 proc sql 轻松完成:

proc sql;
    create table RESULT as
    select *, listen-min(start) as weekSincestart
    from INPUT
    group by id;
quit;

需要每个 id 组的最小值来计算 min(start)。而且由于您选择的变量不在 group by 中,也没有聚合函数,因此它不会将多行聚合为 group by 中的一行。

于 2013-08-04T20:04:57.483 回答
0

你的问题有点令人困惑。如果您只想听减去开始(您的“结果”是什么),那么就这样做。该min函数不跨行;在 SAS 中,很难跨行(或者至少这是您必须故意做的事情)。当然,您确实需要弄清楚如何处理年份障碍;如果我是您,我会将日期保留为实际日期并用于INTCK确定周数的差异。

如果您确实想要整个 ID 的最小值,数据步骤解决方案(不像 SQL 解决方案那样简洁,但工作原理大致相同):

data want;
set have;
by id start;
retain _initial_start;
if first.id then _initial_start=start;
weeksincestart=listen-_initial_start; *or whatever you intended - this does not seem right;
drop _initial_start;
run;
于 2013-08-05T04:01:48.477 回答