我正在尝试根据某些条件对911呼叫的数据帧中的对象进行计数,但是逻辑上遇到了麻烦。我的实际数据有超过300万行,因此我尝试通过考虑以下小子集来简化问题:
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呼叫,“徽章”标识人员,“轮班”基本上标识特定区域中的时间段。呼叫进入的特定分钟数由“ assignedmin”给出,而呼叫在“ clearedmin”给出的时间视为已清除。
我想计算在给定的班次中能够响应特定呼叫的人员数量。例如,对于呼叫14-1234,在时间1902分配了警务人员8456。将有多少其他警务人员能够响应该电话?官员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
我希望这不会太令人费解。基本上,在assignmin给出的时间,如果某个人员在同一班次并且没有被其他呼叫占用,则该人员将可用。我可以很容易地使用dplyr和data.table来计算班次中的警员人数,如下所示:
dat <- dat %>% group_by(shift) %>% mutate(n_shift = uniqueN(badge),
n_shift_male = uniqueN(badge[off.sex == 'Male']) %>% ungroup()
答案 0 :(得分:1)
使用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
答案 1 :(得分:0)
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
可以将其连接到您的桌子上以获得所需的结果。