R语言识别重叠数值范围:构建ID重叠关联网络的实现方法
时间重叠成对计算实现方案
核心计算逻辑
两个时间区间的重叠年数计算公式为:重叠年数 = min(ID1结束年份, ID2结束年份) - max(ID1开始年份, ID2开始年份) + 1
计算结果大于0代表两个ID的时间范围存在重叠,等于或小于0则无重叠。
代码实现
以下提供两种R语言实现方案,均基于你给出的示例数据:
tidyverse 方案(代码可读性高)
library(dplyr) library(tidyr) # 你的示例数据 df <- data.frame( id = 1:5, start_year = c(2010, 2010, 2011, 2013, 2014), end_year = c(2014, 2012, 2018, 2015, 2020)) # 生成成对ID并计算重叠时长 pair_overlap <- df %>% # 生成所有ID两两组合 expand_grid(id1 = .$id, id2 = .$id) %>% # 排除自身配对、避免重复计算相同配对(如1&2和2&1) filter(id1 < id2) %>% # 匹配两个ID的起止时间 left_join(df, by = c("id1" = "id"), suffix = c("_1", "_2")) %>% left_join(df, by = c("id2" = "id"), suffix = c("_1", "_2")) %>% # 计算重叠年数 mutate(overlap_year = pmin(end_year_1, end_year_2) - pmax(start_year_1, start_year_2) + 1) %>% # 过滤无重叠的配对 filter(overlap_year > 0) %>% # 提取最终三元组字段 select(id1, id2, overlap_year) # 输出你需要的逗号分隔格式 apply(pair_overlap, 1, paste, collapse = ", ") %>% cat(sep = "\n")
运行后输出结果如下:
1, 2, 3 1, 3, 4 1, 4, 2 1, 5, 1 2, 3, 2 3, 4, 3 3, 5, 7 4, 5, 2
纯base R方案(无需加载第三方包)
df <- data.frame( id = 1:5, start_year = c(2010, 2010, 2011, 2013, 2014), end_year = c(2014, 2012, 2018, 2015, 2020)) # 生成所有不重复ID配对 id_pairs <- combn(df$id, 2, simplify = FALSE) # 遍历计算每对重叠时长 res_list <- lapply(id_pairs, function(p) { s1 <- df$start_year[df$id == p[1]] e1 <- df$end_year[df$id == p[1]] s2 <- df$start_year[df$id == p[2]] e2 <- df$end_year[df$id == p[2]] overlap <- min(e1, e2) - max(s1, s2) + 1 if (overlap > 0) return(c(p[1], p[2], overlap)) }) # 过滤无重叠配对并整理为数据框 res_df <- do.call(rbind, Filter(Negate(is.null), res_list)) # 输出逗号分隔格式 apply(res_df, 1, paste, collapse = ", ") %>% cat(sep = "\n")
运行结果和tidyverse方案完全一致。
内容的提问来源于stack exchange,提问作者Frank B.
相关产品推荐
相关产品推荐

