Как определить новый столбец в отношении 4 столбцов? - PullRequest
1 голос
/ 21 февраля 2020

Я хочу сделать новый столбец l oop, как показано ниже: Первый столбец - это индекс домохозяйства. второй столбец - это индекс лица в этом домохозяйстве. третий столбец - это показатель поездки каждого дня в каждой семье в течение дня. zoneOfHome - это зона дома этого домашнего хозяйства. start_zone - это зона, откуда человек начинает свое путешествие оттуда, а end_zone - это зона места, куда человек отправляется туда. В последнем столбце указывается, когда человек вернулся домой. L oop - это последовательность поездок, которая начинается дома и заканчивается дома. Я хочу новый столбец 'l oop', который определяет l oop каждой поездки члена домохозяйства.

tibble::tribble(
  ~Household, ~person, ~trip, ~ZoneOfHome, ~start_zone, ~end_zone,   ~purpose,
          1L,      1L,    1L,         22L,         22L,       13L,     0,
          1L,      1L,    2L,         22L,         13L,       22L,     1,
          1L,      1L,    3L,         22L,         22L,       34L,     0,
          1L,      1L,    4L,         22L,         34L,       22L,     1,
          1L,      2L,    1L,         22L,         22L,       13L,     0,
          1L,      2L,    2L,         22L,         13L,       22L,     1,
          2L,      1L,    1L,         15L,         15L,       15L,     0,
          2L,      1L,    2L,         15L,         15L,       15L,     1,
          2L,      1L,    3L,         15L,         15L,       45L,     0,
          2L,      1L,    4L,         15L,         45L,       15L,     1,
          3L,      1L,    1L,         17L,          6L,       17L,     1,
          3L,      1L,    2L,         17L,         17L,       10L,     0,
          3L,      1L,    3L,         17L,         10L,       17L,     1
  )

Для каждого человека al oop начинается, когда start_zone=zone до тех пор, пока показатель не станет равным 1 .

Household   person    trip    ZoneOfHome    start_zone   end_zone       loop
   1           1        1      22              22           13            1
   1           1        2      22              13           22            1
   1           1        3      22              22           34            2
   1           1        4      22              34           22            2
   1           2        1      22              22           13            1
   1           2        2      22              13           22            1
   2           1        1      15              15           15            1
   2           1        2      15              15           15            1
   2           1        3      15              15           45            2
   2           1        4      15              45           15            2
   3           1        1      17              6            17            -
   3           1        2      17              17           10            1
   3           1        3      17              10           17            1

1 Ответ

1 голос
/ 06 марта 2020

В дополнительном столбце purpose добавлена ​​информация, которая значительно упрощает идентификацию циклов, чем в исходном вопросе . Если я правильно понимаю, purpose равно 1, если пункт назначения - это дом человека.

library(data.table)
setDT(DT)[, loop := cumsum(start_zone == ZoneOfHome & purpose != 1), by = .(Household, person)][]
    Household person trip ZoneOfHome start_zone end_zone purpose loop
 1:         1      1    1         22         22       13       0    1
 2:         1      1    2         22         13       22       1    1
 3:         1      1    3         22         22       34       0    2
 4:         1      1    4         22         34       22       1    2
 5:         1      2    1         22         22       13       0    1
 6:         1      2    2         22         13       22       1    1
 7:         2      1    1         15         15       15       0    1
 8:         2      1    2         15         15       15       1    1
 9:         2      1    3         15         15       45       0    2
10:         2      1    4         15         45       15       1    2
11:         3      1    1         17          6       17       1    0
12:         3      1    2         17         17       10       0    1
13:         3      1    3         17         10       17       1    1

Объяснение

ОП определил

A l oop - это последовательность поездок, которая начинается из дома и заканчивается дома.

Итак, нам нужно определить, какие поездки начинаются дома , Эта информация не дается явно, но может быть получена из условия start_zone == ZoneOfHome & purpose != 1, т. Е. Поездка начинается в домашней зоне, но не отправляется домой. Выражение cumsum(start_zone == ZoneOfHome & purpose != 1) увеличивается на единицу всякий раз, когда начинается новый l oop (для каждого члена семьи).

Улучшенная версия:

Обратите внимание, что мы не проверяем явно для конец поездки, т. е. purpose == 1. Предполагается, что поездка, которая начинается в домашней зоне и не идет домой, начинается дома, а предыдущая поездка закончилась дома. Это может быть неверно для более сложных схем поездок.

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

setDT(DT)[, loop := cumsum(start_zone == ZoneOfHome & shift(purpose, fill = 1) == 1), 
          by = .(Household, person)][]

результат для вышеуказанного набора данных такой же, как и выше.

Итак, новый l oop начинается из дома, если начальная точка находится в домашней зоне, а предыдущая поездка закончилась дома.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...