在 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
我正在尝试在 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