Умножьте и вычтите значения в предыдущей строке для новой строки в FoxPro - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь написать команду в fox pro, которая помогает мне вычислить две переменные в таблице, которая выглядит следующим образом:

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) - ( мертвый в возрасте х-1)

мертвый в возрасте х = (death_rate в возрасте х) * (живой в возрасте х)

Я пытаюсь вычислить остальные значения для живых и автоматически отключается, но два пустых столбца зависят друг от друга в расчете, я не уверен, как должна выглядеть команда

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Я не могу дать вам одну команду, чтобы сделать это, но это сравнительно легко, если вы используете небольшую программу. Я не знаю, какой тип файла данных вы используете (таблица VFP, таблица MS SQL), поэтому я продемонстрирую с помощью курсора VFP. Вы можете открыть новое окно программы в VFP, введя MODIFY COMMAND в командном окне. Вставьте следующий код в окно программы, выделите код, щелкните правой кнопкой мыши и выберите «Выполнить выбор».

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
0 голосов
/ 09 февраля 2020

Это довольно болезненно в Foxpro, потому что у него нет оконных функций. Вы можете использовать совокупный 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;

Обратите внимание, что производительность будет не очень хорошей. Я бы порекомендовал вам перейти на более производительную базу данных, особенно ту, которая поддерживает оконные функции.

...