在 FoxPro 中为新行乘以和减去前一行中的值

Multiply and subtract values in previous row for new row in FoxPro

我正在尝试在 fox pro 中编写命令,帮助我计算 table 中的两个变量,看起来像这样

age   death_rate   alive   dead
1      0.003       1000     3
2      0.001       997      1
3      0.0006
4      0.005
5      0.002
...

在 x 岁时活着 =(在 x-1 岁时活着)-(在 x-1 岁时去世)

在 x 岁时去世 = (death_rate 在 x 岁时) * (在 x 岁时活着)

我正在尝试自动计算 alive 和 dead 的其余值,但是两个空列在计算中相互依赖,我不确定命令应该是什么样子

这在 Foxpro 中相当痛苦,因为它没有 window 功能。您可以使用带有对数和求幂的累积 sum()。因此,要计算 alive 列:

select t.*,
       (select coalesce(1000 * exp(sum(log(1.0 - deathrate)), 1000)
        from t t2
        where t2.age < t.age
       ) as alive
from t;

然后可以使用子查询来计算死:

select t.*,
       (alive * (1 - deathrate)) as dead
from (select t.*,
             (select coalesce(1000 * exp(sum(log(1.0 - deathrate)), 1000)
              from t t2
              where t2.age < t.age
             ) as alive
      from t
     ) t;

请注意,性能不会很好。我建议您升级到性能更高的数据库,尤其是支持 window 函数的数据库。

我不能给你一个命令来做到这一点,但如果你使用一个小程序就相对容易了。我不知道您使用的是什么数据文件类型(VFP table、MSSQL table),所以我将使用 VFP 游标进行演示。您可以通过在命令 window 中键入 MODIFY COMMAND 在 VFP 中打开一个新程序 window。将以下代码粘贴到程序中 window,突出显示代码,右键单击并执行选择。

CREATE CURSOR deathrate (age i,death_rate n(6,4),alive i, dead i)
INSERT INTO deathrate (age,death_rate,alive,dead) VALUES (1,.003,1000,3)
INSERT INTO deathrate (age,death_rate,alive,dead) VALUES (2,.001,997,1)
INSERT INTO deathrate (age,death_rate,alive,dead) VALUES (3,.0006,0,0)
INSERT INTO deathrate (age,death_rate,alive,dead) VALUES (4,.005,0,0)
INSERT INTO deathrate (age,death_rate,alive,dead) VALUES (5,.002,0,0)
GOTO 2 && you have supplied the first 2 values, go to record 2
SCATTER NAME oprev  && create a scattered object of the current record, then...
SKIP    && skip 1 record
SCAN rest
    replace alive WITH oprev.alive - oprev.dead, dead WITH round(death_rate * alive,0)
    SCATTER NAME oprev    && refresh before skipping to next record
ENDSCAN
BROWSE NORMAL LAST

结果是:

      AGE DEATH_RATE       ALIVE        DEAD
        1     0.0030        1000           3
        2     0.0010         997           1
        3     0.0006         996           1
        4     0.0050         995           5
        5     0.0020         990           2