同一表中重叠的日期时间数(R)
我有一个大约50000行的表,有四列同一表中重叠的日期时间数(R),r,datetime,overlap,R,Datetime,Overlap,我有一个大约50000行的表,有四列 ID Arrival Departure Gender 1 10/04/2015 23:14 11/04/2015 00:21 F 1 11/04/2015 07:59 11/04/2015 08:08 F 3 10/04/2017 21:53 30/03/2017 23:37 M 3 31/03/2017
ID Arrival Departure Gender
1 10/04/2015 23:14 11/04/2015 00:21 F
1 11/04/2015 07:59 11/04/2015 08:08 F
3 10/04/2017 21:53 30/03/2017 23:37 M
3 31/03/2017 07:09 31/03/2017 07:57 M
3 01/04/2017 01:32 01/04/2017 01:35 M
3 01/04/2017 13:09 01/04/2017 14:23 M
6 10/04/2015 21:31 10/04/2015 23:17 F
6 10/04/2015 23:48 11/04/2015 00:05 F
6 01/04/2016 21:45 01/04/2016 22:48 F
6 02/04/2016 04:54 02/04/2016 07:38 F
6 04/04/2016 18:41 04/04/2016 22:48 F
10 10/04/2015 22:39 11/04/2015 00:42 M
10 13/04/2015 02:57 13/04/2015 03:07 M
10 31/03/2016 22:29 01/04/2016 08:39 M
10 01/04/2016 18:49 01/04/2016 19:44 M
10 01/04/2016 22:28 02/04/2016 00:31 M
10 05/04/2017 09:27 05/04/2017 09:28 M
10 06/04/2017 15:12 06/04/2017 15:43 M
这是该表的一个非常小的表示形式。我想知道的是,在每次参赛的同时,还有多少人在场,然后按性别将他们分开。例如,假设在ID为1的人第一次出现时,ID为6的人出现,ID为10的人在同一时间间隔内出现两次。这意味着,与此同时,发生了另外两个重叠。这也意味着ID为1的人与1名男性和1名女性重叠
因此,其结果应该如下所示:
ID Arrival Departure Males encountered Females encountered
1 10/04/2015 23:14 11/04/2015 00:21 1 1
我怎样才能计算出这个呢?我曾尝试使用foverlaps,并成功地用Excel解决了这一问题,但我希望在R中实现这一点。这里有一种可能性。这将使用和int_overlaps函数查找日期重叠。但这有一个缺点:间隔。所以这个版本只是在for循环中手动完成所有工作 它首先创建一个与您的数据集相匹配的1000行随机数据集:每个人在两年内到达,然后在一两天后离开 1000次跑步大约需要24秒,所以你可以预计50次跑步需要一段时间!for循环输出行号,以便您可以看到它在哪里 任何关于密码的问题,让我知道 必须有一种更快的矢量化方法,但interval似乎也不能很好地使用apply。其他人可能会有更快的 最终输出看起来像
库(tidyverse)
图书馆(lubridate)
#样本数据:
#(日期取样代码:https://stackoverflow.com/questions/21502332/generating-random-dates)
#2017年至2019年之间的随机日期
x%
总结(count=n())%>%#获得每个性别的每个重叠的观察计数
完成(性别,填充=列表(计数=0))#需要此项来保持零计数:否则汇总会删除它们
#我们想在他们自己的专栏中为每种性别统计,所以请广泛使用
性别计数%
排列(键=性别,值=计数)
#存储以便很快转换为数据帧
性别计数[[length(gendercounts)+1]]这里是一个数据表
使用foverlaps的解决方案
首先,请注意您的数据中有一个错误:
ID Arrival Departure Gender
3 10/04/2017 21:53 30/03/2017 23:37 M
用户在实际离开后将近一个月到达。为了运行foverlaps
,我需要清除这些数据
library(data.table)
dt <- data.table(df)
dt <- dt[Departure > Arrival, ] # filter wrong cases
setkey(dt, "Arrival", "Departure") # prepare for foverlaps
dt2 <- copy(dt) # use a different dt, inherits the key
将列顺序设置为更好的顺序
我无法将您的输出链接到示例数据。。遇到的男性==1
来自哪里?您的示例数据似乎不包含任何重叠的时段…我现在做了一个小的更改,以便反映输出。谢谢你指出这一点,并对由此带来的不便表示歉意。你认为这对约会时间也适用吗?或者只写日期,包括年、月和日。是的,也应该写时间。这个在同一天重叠时间的小例子很好。您只需确保日期时间列已转换为日期时间对象。如果您使用tidyverse的read_csv加载,我认为它应该自动加载by.x中最后两列中的一列应与data.table“x”中的“开始”和“结束”间隔相对应,并且必须是整数/数字类型。我在尝试同时运行命令时遇到此错误。这意味着您的到达
(很可能您的离开
)列仍然是文本,而不是日期。尝试并研究lubridate::ymd_hm
和类似函数,将字符列转换为setkey
之前的日期编辑您的问题并粘贴dput(head(df))
的结果,我很乐意解决您遇到的问题,因此,我编辑了代码,并将到达和离开日期转换为日期。代码运行时没有问题,但某些行保留为NAs而不是计数。
library(data.table)
dt <- data.table(df)
dt <- dt[Departure > Arrival, ] # filter wrong cases
setkey(dt, "Arrival", "Departure") # prepare for foverlaps
dt2 <- copy(dt) # use a different dt, inherits the key
simultaneous <- foverlaps(dt, dt2)[i.Arrival <= Arrival & ID != i.ID,
.(malesEncountered = sum(i.Gender == "M"),
femalesEncountered = sum(i.Gender == "F")),
by = .(ID, Arrival)]
result <- simultaneous[dt, on = .(ID, Arrival)]
result[is.na(malesEncountered), malesEncountered := 0][
is.na(femalesEncountered), femalesEncountered := o]
setcolorder(result, c(1, 2, 5, 6, 3, 4))[]