Используя R, как я могу считать объекты в соответствии с несколькими условиями? - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь считать объекты в кадре данных 911 вызовов в соответствии с определенными условиями, и у меня возникают проблемы с логи c. Мои фактические данные содержат более 3 миллионов строк, поэтому я попытался упростить мою проблему, рассмотрев это небольшое подмножество:

dat <- structure(list(call = c("14-1234", "14-4523", "14-7711", "14-8199", "14-3124"), 
                      badge = c("8456", "1098", "3432", "4750", "5122"),
                      off.sex = c("Male", "Male", "Female", "Male", "Male"),
                      shift = c("1", "1", "1", "1", "2"),
                      assignedmin = c(1902, 1870, 1950, 1899, 1907),
                      clearedmin = c(1980, 1910, 1990, 1912, 1956)),
                 class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L))

Переменная «call» идентифицирует 911 вызовов, «badge» определяет офицеров, «shift» «в основном определяет отрезок времени в конкретной области. Конкретная c минута, в которую поступает вызов, дается «назначенным», и вызов считается сброшенным в момент, заданный «очищенным».

Я хочу посчитать, сколько офицеров в данной смене могут ответить на конкретный звонок. Например, для звонка 14-1234 сотрудник 8456 назначается в момент 1902 года. Сколько других офицеров смогли бы ответить на этот звонок? Офицер 1098 был озабочен другим вызовом с минуты 1870 до минуты 1910, и поэтому не смог бы ответить на вызов, происходящий на минуте 1902. Однако, основываясь на этом простом наборе данных, сотрудник 3432 не был бы занят в это время и так будет считаться доступным. Офицер 5122 в то время не был занят, но находился в другой смене и поэтому не считался доступным.

Желаемый результат:

  call    badge off.sex shift assignedmin clearedmin n_shift n_avail n_unavail n_shift_male n_male_avail
1 14-1234 8456  Male    1            1902       1980       4       2         2            3            1
2 14-4523 1098  Male    1            1870       1910       4       4         0            3            3
3 14-7711 3432  Female  1            1950       1990       4       3         1            3            2
4 14-8199 4750  Male    1            1899       1912       4       3         1            3            2
5 14-3124 5122  Male    2            1907       1956       1       1         1            1            1

Надеюсь, это не слишком запутанно. Как правило, во время, назначенное назначенным министром, сотрудник доступен, если он или она находится в той же смене и не занят другим вызовом. Я могу легко посчитать количество офицеров в смену, используя dplyr и data.table следующим образом:

dat <- dat %>% group_by(shift) %>% mutate(n_shift = uniqueN(badge),
                                          n_shift_male = uniqueN(badge[off.sex == 'Male']) %>% ungroup()

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Опция, использующая data.table для подсчета количества офицеров в смену, затем выполнить неравное самостоятельное объединение, чтобы выяснить n_unavail и, наконец, n_avail = n_shift - n_unavail:

library(data.table)
setDT(dat)[, c("n_shift", "n_shift_male") := .(.N, sum(off.sex=="Male")), shift]

dat[, c("n_unavail", "n_male_not_avail") :=
        dat[dat, on=.(shift, assignedmin<=assignedmin, clearedmin>=assignedmin),
            by=.EACHI, .(.N - 1L, sum(x.off.sex[x.call != i.call]=="Male"))][,
                (1L:3L) := NULL]
    ]

dat[, c("n_avail", "n_male_avail") := .(n_shift - n_unavail, n_shift_male - n_male_not_avail)]

вывод:

      call badge off.sex shift assignedmin clearedmin n_shift n_shift_male n_unavail n_male_not_avail n_avail n_male_avail
1: 14-1234  8456    Male     1        1902       1980       4            3         2                2       2            1
2: 14-4523  1098    Male     1        1870       1910       4            3         0                0       4            3
3: 14-7711  3432  Female     1        1950       1990       4            3         1                1       3            2
4: 14-8199  4750    Male     1        1899       1912       4            3         1                1       3            2
5: 14-3124  5122    Male     2        1907       1956       1            1         0                0       1            1
0 голосов
/ 15 апреля 2020

Столбец n_unavail можно заполнить, как показано ниже. Во-первых, я присоединяюсь к таблице отдельно shift, так что для каждой комбинации офицеров в одну смену есть ряд (это может быть невозможно, если ваш набор данных большой). Затем я вычисляю, недоступен ли сотрудник _other во время вызова, и подсчитываю его.

dat %>% 
  left_join(dat, by = "shift", suffix = c("", "_other")) %>% 
  mutate(unavail = (assignedmin_other < assignedmin & clearedmin_other > assignedmin)) %>% 
  group_by(call) %>% 
  summarise(n_avail = sum(!unavail),
            n_unavail = sum(unavail))

#   call    n_avail n_unavail
#   <chr>     <int>     <int>
# 1 14-1234       2         2
# 2 14-3124       1         0
# 3 14-4523       4         0
# 4 14-7711       3         1
# 5 14-8199       3         1

Это можно присоединить к вашему столу, чтобы получить желаемый результат.

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