2

我有以下数据集:

AGE    HSQ    PCT

65      1     0.7
65      2     0.2
65      3     0.1
66      1     0.5
66      2     0.25
66      3     0.25

[...]

我需要的是获得以下输出:

AGE     P1    P2     P3

65     0.7    0.2    0.1
66     0.5    0.25   0.25

[...]

我被告知要采用LAG或为了做到这一点,对我来说这似乎是一个很好的策略FIRST.AGELAST.AGE但是我无法获得最终结果..我使用的(错误)代码是:

DATA OUTPUT;
  SET SAMPLE;
    BY AGE HSQ;
  IF LAST.AGE THEN DO;
    P1=LAG2(PCT);
    P2=LAG1(PCT);
    P3=PCT;
  END;
RUN;

但它跳到以前的年龄百分比,这不是我需要的..语法错误在哪里?谢谢!

4

2 回答 2

3

被告知这是使用它们的任务,或者这是最简单的方法?

最简单的方法是 PROC TRANSPOSE:

data have;
input AGE    HSQ    PCT;
datalines;
65      1     0.7
65      2     0.2
65      3     0.1
66      1     0.5
66      2     0.25
66      3     0.25
;;;;
run;

proc transpose data=have out=want prefix=P;
by age;
var pct;
id hsq;
run;

LAG 不会按照您认为的方式工作 - 它不会您提供前一行的值;相反,它会创建一个队列并获取 (argument) 的当前值,并为您提供队列中的前一个值。所以你不能在这样的 IF 语句中使用它。

如果您出于某种原因必须在数据步中执行此操作,那么您可能希望这样做:

data want;
array p[3];
do _n_ = 1 by 1 until (last.age);
    set have;
    by age;
    p[hsq]=pct;
end;
keep p1-p3 age;
run;

真的没有理由使用滞后,或任何滞后的概念;就像你遇到属于某个地方的值一样,你将它们分配给那个地方,当你点击 last.age 然后输出。

有人想和我一起提出 SASware 请求以删除 LAG 功能吗?

于 2012-10-10T14:09:27.853 回答
2

只是为了好玩,对原始问题的直接回答(展示如何做到这一点):

DATA want;
  SET have;
    BY AGE HSQ;
    p1=lag2(pct);
    p2=lag1(pct);
    p3=pct;
    if last.age then output;
run;

这需要做很多额外的工作(当然,我指的是几纳秒的 CPU 时间),因为它计算了六次滞后,并且只输出了两个结果。它也有点“冒险”,因为它不会检查以确保 HSQ 是正确的值 - 即,如果您错过了一个年龄的条目,并且只有 2 行,那么您将拥有前一个年龄的 HSQ = P1 的 3 值,这可能是不希望的。

最后一点是,对于 LAG,如果您确实打算将其用作“前一行的记录”的替代品,则需要将其保留在条件块之外。计算每一行的滞后,并有条件地使用结果(在这种情况下,有条件地使用输出)。

于 2012-10-10T15:18:55.663 回答