如何在R中按ID统计两个数据框的日期精确匹配数
解决按ID统计两个数据框匹配天数的问题
问题分析
需要统计每个ID在两个数据框中同时出现的date数量,包括仅在一个数据框中出现的ID(计数为0),且数据量达400万条,需兼顾效率。
解决方案
方法1:Base R 实现
适合不想加载额外包的场景,逻辑清晰:
# 生成ID-date唯一标识(用interaction组合) DF1$key <- interaction(DF1$ID, DF1$date) DF2$key <- interaction(DF2$ID, DF2$date) # 提取两个表共有的ID-date对 common_keys <- intersect(DF1$key, DF2$key) # 按ID统计匹配数量 counts <- table(sub("\\..*", "", common_keys)) # 收集所有出现过的ID,补全无匹配的ID计数为0 all_ids <- unique(c(DF1$ID, DF2$ID)) result <- data.frame( ID = all_ids, Count = as.integer(counts[as.character(all_ids)]) ) result$Count[is.na(result$Count)] <- 0 result <- result[order(result$ID), ]
方法2:dplyr(tidyverse)实现
代码更简洁,可读性强:
library(dplyr) result <- DF1 %>% # 内连接筛选出两个表都存在的ID-date对 inner_join(DF2, by = c("ID", "date")) %>% # 按ID统计匹配次数 count(ID, name = "Count") %>% # 关联所有出现过的ID,确保无匹配的ID被保留 right_join(tibble(ID = unique(c(DF1$ID, DF2$ID))), by = "ID") %>% # 将无匹配的ID计数替换为0 mutate(Count = replace_na(Count, 0)) %>% # 按ID排序 arrange(ID)
方法3:data.table 实现
针对400万条大数据量优化,执行速度最快:
library(data.table) # 转换为data.table格式 setDT(DF1) setDT(DF2) # 内连接筛选匹配的ID-date对,按ID计数 counts <- DF1[DF2, on = .(ID, date), nomatch = 0][, .(Count = .N), by = ID] # 收集所有ID,左连接后补全无匹配的计数为0 all_ids <- unique(c(DF1$ID, DF2$ID)) result <- counts[.(ID = all_ids), on = .(ID)][is.na(Count), Count := 0][order(ID)]
对您之前尝试的问题说明
aggregate方法:将两个表rbind后无法区分来源,且which参数的用法不符合aggregate的函数要求,无法直接筛选出两个表共有的date。table方法:仅筛选了ID存在交集的样本,但未处理date的匹配逻辑,无法统计具体的共同天数。
内容的提问来源于stack exchange,提问作者Tanya
相关产品推荐
相关产品推荐

