如何判断日期是否在区间?R实现电话数据与滚动30天区间匹配
实现滚动日期区间的通话标记矩阵
针对你想要构建手机号为行、滚动30天区间为列的标记矩阵需求,我们可以用R的dplyr、fuzzyjoin和tidyr包来高效实现,避开复杂的groupby操作。下面一步步拆解解决:
1. 先解决日期区间判断的基础问题
在R里判断单个日期是否落在start和end区间内,直接用逻辑运算符就能搞定:
# 示例:判断某日期是否在指定区间内 target_date <- as.Date("2019-03-01") start <- as.Date("2019-02-28") end <- as.Date("2019-03-30") # 返回TRUE/FALSE target_date >= start & target_date <= end
但要批量关联两个数据集,用模糊连接会更高效,不用循环遍历每个区间。
2. 关联通话数据与滚动区间数据
首先加载所需工具包,然后定义你的原始数据:
library(dplyr) library(fuzzyjoin) library(tidyr) # 你的通话数据集 Date <- as.Date(c("2019-03-01", "2019-03-15","2019-03-29", "2019-04-10","2019-03-05","2019-03-20")) Phone <- c("070000001","070000001","070000001","070000001","070000002","070000002") df <- data.frame(Date, Phone) # 滚动30天区间数据集,同时给每个区间加唯一标识(INT_1、INT_2...) dates <- data.frame(start = seq(as.Date("2016/7/1"), as.Date("2019/7/1"),"days")) %>% mutate( end = start + 30, interval_id = paste0("INT_", row_number()) # 给区间命名,方便后续转宽格式 )
接下来用fuzzy_inner_join实现按日期区间匹配,把每条通话记录和所有包含它的滚动区间关联起来:
# 模糊连接:匹配df$Date 落在 dates$start 和 dates$end 之间的所有记录 joined_data <- fuzzy_inner_join( df, dates, by = c("Date" = "start", "Date" = "end"), match_fun = list(`>=`, `<=`) # 匹配规则:Date >= start 且 Date <= end )
这一步会生成每条通话记录对应的所有符合条件的区间,为后续构建矩阵打基础。
3. 构建目标标记矩阵
最后用pivot_wider把数据转成你想要的宽格式,并用"X"标记存在匹配的区间:
# 转成宽格式,生成目标矩阵 result_matrix <- joined_data %>% # 按原始通话日期和手机号分组,保留每条通话记录的信息 group_by(Date, Phone) %>% summarise(intervals = list(interval_id), .groups = "drop") %>% # 转宽:区间为列,存在则标X pivot_wider( names_from = intervals, values_from = intervals, values_fill = "", values_fn = function(x) ifelse(length(x) > 0, "X", NA) )
运行后得到的result_matrix就和你期望的格式一致:每行是一条通话记录,每列是一个滚动区间,手机号在该区间有通话则标"X",否则为NA(你可以根据需求替换成空白)。
可选:按手机号汇总所有区间
如果你希望每个手机号只占一行,汇总它所有通话日期对应的区间,可以调整为:
summary_matrix <- joined_data %>% distinct(Phone, interval_id) %>% # 去重,保留每个手机号对应的所有区间 pivot_wider( names_from = interval_id, values_from = interval_id, values_fill = NA, values_fn = function(x) "X" )
内容的提问来源于stack exchange,提问作者Jacob Baisley
相关产品推荐
相关产品推荐

