r - 按组在多个时间间隔列之间重叠
问题描述
前几天我打开了这个相关的帖子:Time-interval overlay match by group
但是,现在我必须处理这样一个事实,即我需要重叠多个时间间隔列并在发生这种情况时返回 flag = 1 的第一个row_number值。
例如我有以下df:
id flag row_number time_1 time_2 result
1 1 1 2001-04-01 UTC--2001-05-01 UTC 1960-01-01 UTC--1962-01-01 UTC NA
1 1 2 2007-08-01 UTC--2007-12-01 UTC 1980-01-01 UTC--1982-01-01 UTC NA
1 1 3 2010-03-01 UTC--2011-03-01 UTC 1949-01-01 UTC--1951-01-01 UTC NA
1 0 4 2001-04-15 UTC--2001-04-20 UTC 1981-01-01 UTC--1983-01-01 UTC NA
1 0 5 2001-04-17 UTC--2001-05-15 UTC 1959-01-01 UTC--1961-01-01 UTC 1
1 0 6 2007-09-01 UTC--2007-12-01 UTC 1980-01-01 UTC--1983-01-01 UTC 2
1 0 7 2011-01-01 UTC--2011-03-05 UTC 1994-01-01 UTC--1996-01-01 UTC NA
1 0 8 2018-01-01 UTC--2017-12-01 UTC 1949-01-01 UTC--1951-01-01 UTC NA
使用以下代码创建:
library(dplyr)
library(purrr)
library(lubridate)
df <- data.frame(id=c(1, 1, 1, 1, 1, 1, 1, 1),
flag=c(1, 1, 1, 0, 0, 0, 0, 0),
row_number=c(1,2,3,4,5,6,7,8),
time_1=c(interval(ymd(20010401), ymd(20010501)),
interval(ymd(20070801), ymd(20071201)),
interval(ymd(20100301), ymd(20110301)),
interval(ymd(20010415), ymd(20010420)),
interval(ymd(20010417), ymd(20010515)),
interval(ymd(20070801), ymd(20071201)),
interval(ymd(20110101), ymd(20110305)),
interval(ymd(20180101), ymd(20171201))),
time_2=c(interval(ymd(19600101), ymd(19620101)),
interval(ymd(19800101), ymd(19820101)),
interval(ymd(19490101), ymd(19510101)),
interval(ymd(19810101), ymd(19830101)),
interval(ymd(19590101), ymd(19610101)),
interval(ymd(19800101), ymd(19820101)),
interval(ymd(19940101), ymd(19960101)),
interval(ymd(19490101), ymd(19510101))),
result = c(NA, NA, NA, NA, 1, 2, NA, NA))
也就是说,我需要找到与标志 = 0 的行的time_1和time_2的重叠,其中标志 = 1 的行的所有 time_1 和 time_2 变量。
结果应该是具有标志 0 的行与具有重叠 time_1 和 time_2 间隔的具有标志 1 的行之间的第一个匹配的row_number值的列。为此,我尝试了 lubridate 包中的 int_overlap() 函数。
使用此代码,我可以利用 map_int() 函数确定标志 = 0 的一行与标志 == 1的任何行之间是否存在 time_1 重叠
library(tidyverse)
library(lubridate)
df %>%
group_by(id) %>%
mutate(value = ifelse(flag == 0, map_int(time_1, ~ any(int_overlaps(.x, time_1[flag == 1]))), NA))
一个可能有用的相关问题: R Find重叠时间段
编辑:我想获得一个用row_number 变量标识的列,它是第一个标志1 行,它具有time_1 和time_2 与标志0 行重叠的值。
id flag row_number time_1 time_2 result
1 1 1 2001-04-01 UTC--2001-05-01 UTC 1960-01-01 UTC--1962-01-01 UTC NA
1 0 5 2001-04-17 UTC--2001-05-15 UTC 1959-01-01 UTC--1961-01-01 UTC 1
例如 row_number 1 和 5 满足条件。结果是一个整数列,表示 row_number 5(标志 0 行)具有 time_1 和 time_2 与 row_number 1(标志 1)重叠。
希望这可以澄清。
解决方案
这是data.table
通过执行重叠连接两次来使用的选项:
setkey(setDT(df), id, time_1_start, time_1_end)
ol1 <- foverlaps(df, df, nomatch=0L)[
row_number!=i.row_number & i.flag==0L & flag==1L,
.(id, irn=i.row_number, rn=row_number, flag=i.flag,
time_2_start=i.time_2_start, time_2_end=i.time_2_end)]
setkey(df, id, time_2_start, time_2_end)
setkey(ol1, id, time_2_start, time_2_end)
olaps <- foverlaps(ol1, df)[row_number!=irn & row_number==rn & i.flag==0L & flag==1L,
.(id, irn, xrn=row_number)]
df[olaps, on=.(id, row_number=irn), res := xrn]
setorder(df, row_number)
df
输出:
id flag row_number time_1_start time_1_end time_2_start time_2_end res
1: 1 1 1 2001-04-01 2001-05-01 1960-01-01 1962-01-01 NA
2: 1 1 2 2007-08-01 2007-12-01 1980-01-01 1982-01-01 NA
3: 1 1 3 2010-03-01 2011-03-01 1949-01-01 1951-01-01 NA
4: 1 0 4 2001-04-15 2001-04-20 1981-01-01 1983-01-01 NA
5: 1 0 5 2001-04-17 2001-05-15 1959-01-01 1961-01-01 1
6: 1 0 6 2007-08-01 2007-12-01 1980-01-01 1982-01-01 2
7: 1 0 7 2011-01-01 2011-03-05 1994-01-01 1996-01-01 NA
8: 1 0 8 2017-12-01 2018-01-01 1949-01-01 1951-01-01 NA
数据:
library(data.table)
dtfun <- function(x) as.IDate(x, format="%Y%m%d")
df <- data.frame(id=c(1, 1, 1, 1, 1, 1, 1, 1),
flag=c(1, 1, 1, 0, 0, 0, 0, 0),
row_number=c(1,2,3,4,5,6,7,8),
time_1_start=dtfun(c("20010401","20070801","20100301","20010415",
"20010417","20070801","20110101","20171201")),
time_1_end=dtfun(c("20010501","20071201","20110301","20010420","
20010515","20071201","20110305","20180101")),
time_2_start=dtfun(c("19600101","19800101","19490101","19810101",
"19590101","19800101","19940101","19490101")),
time_2_end=dtfun(c("19620101","19820101","19510101","19830101",
"19610101","19820101","19960101","19510101")))
推荐阅读
- reactjs - httpOnly cookie 中的 JWT,cors 仅允许客户端域,csrf 令牌。我的架构有多安全?
- android - 如何将一个视图约束在两个可见性可以切换的视图之下?
- python - 文本与文件文本不匹配,即使它与 Tkinter 匹配
- python - 如何将用 C 编写的 Win32 DLL 导入 Python?
- python - MS VSC Flask tutorial cannot debug
- r - R 中的 Webscraping:处理内容未编码时 curl 出错:数据检查不正确
- firebase - Firestore 安全规则允许 2 个用户之间共享内容?
- c# - 添加后代时 Xamarin 形成 ScrollView 抖动
- c# - 使用每种语言的多个 resx 文件进行本地化
- java - 在Java中为flatbuffer序列化结构向量