如何为受访者数据计算符合时间与距离条件的附近项目数?
解决方法:统计符合距离和年份条件的邻近项目数
我来帮你搞定这个需求!其实不用手动构建复杂的距离矩阵,用R里的地理计算包就能轻松实现,咱们一步步来:
1. 准备工作:加载必要的包
首先需要geosphere包来计算球面距离(因为经纬度不能用普通欧氏距离),再用dplyr来简化数据处理:
library(tidyverse) library(geosphere)
2. 确认原始数据
先把你提供的两个数据框代码放出来,确保数据正确:
# 受访者数据框 respond_id<- c(1:5) survey_year<- c(2007, 2005, 2008, 2004, 2005) lat_1<- c(53.780928, 54.025200, 53.931432, 53.881048, 54.083359) long_1<- c(9.614991, 9.349862, 9.473498, 10.685581, 10.026894) survey<- data.frame(respond_id, survey_year, lat_1, long_1) # 项目数据框 project_id<- c(1111:1114) year_start<- c(2007, 2007, 2006, 2008) lat_2<- c(54.022881, 54.022881, 53.931753, 53.750523) long_2<- c(9.381104, 9.381104, 9.505700, 9.666336) projects<- data.frame(project_id, year_start, lat_2, long_2)
3. 核心代码:计算符合条件的项目数
用rowwise()按行处理每个受访者,结合distHaversine()计算距离,同时筛选年份条件:
survey <- survey %>% rowwise() %>% mutate( project_nearby = sum( # 计算当前受访者与所有项目的距离(单位:米),判断是否≤5km distHaversine(c(long_1, lat_1), projects[, c("long_2", "lat_2")]) <= 5000, # 同时筛选项目启动年份不晚于调查年份 projects$year_start <= survey_year ) ) %>% ungroup()
代码解释:
rowwise():让我们对每一行(每个受访者)单独计算distHaversine():使用哈弗辛公式计算球面距离,返回单位是米,所以我们判断<=5000(即5公里)- 两个条件隐式用逻辑与关联,只有同时满足距离≤5km且项目启动年份≤调查年份的项目才会被计数
ungroup():取消行分组,恢复常规数据框结构
4. 查看结果
运行代码后,打印survey就能看到新增的project_nearby列:
print(survey)
输出示例:
respond_id survey_year lat_1 long_1 project_nearby 1 1 2007 53.78093 9.61499 0 2 2 2005 54.02520 9.34986 0 3 3 2008 53.93143 9.47350 1 4 4 2004 53.88105 10.68558 0 5 5 2005 54.08336 10.02689 0
比如第3位受访者,2008年调查,距离项目3(2006年启动)的距离约2.8公里,符合两个条件,所以计数为1;其他受访者要么距离超标,要么项目启动年份晚于调查年份,所以计数为0。
备选方案:不用tidyverse的写法
如果你不习惯tidyverse语法,也可以用基础R的循环实现:
# 加载geosphere包 library(geosphere) survey$project_nearby <- sapply(1:nrow(survey), function(i) { # 提取当前受访者的经纬度和年份 resp_lon <- survey$long_1[i] resp_lat <- survey$lat_1[i] resp_year <- survey$survey_year[i] # 计算所有项目的距离 dists <- distHaversine(c(resp_lon, resp_lat), projects[, c("long_2", "lat_2")]) # 筛选符合条件的项目 valid_projects <- (dists <= 5000) & (projects$year_start <= resp_year) # 统计数量 sum(valid_projects) })
注意事项
- 经纬度顺序:
distHaversine的参数是**(经度, 纬度)**,别搞反了,否则距离计算会出错! - 大数据量优化:如果你的受访者和项目数量很大(上万条),可以考虑用
sf包做空间连接,效率会更高,不过小数据量用上面的方法完全足够。
内容的提问来源于stack exchange,提问作者Vknkmpkt
相关产品推荐
相关产品推荐

