在R中仅通过国家名称计算地理距离并生成Distance列
计算国家间地理距离的解决方案
1. 先获取国家质心的经纬度
你可以通过两种方式获取国家质心的经纬度数据,按需选择:
方法一:利用countrycode直接提取
countrycode包支持从国家名称直接转换得到质心的经纬度,操作简洁:
# 加载必要的包 library(countrycode) library(geosphere) library(dplyr) # 先取消数据分组(你的数据是分组状态,会影响后续操作) Team5 <- Team5 %>% ungroup() # 新增经纬度列 Team5 <- Team5 %>% mutate( lon = countrycode(Country, "country.name", "longitude"), lat = countrycode(Country, "country.name", "latitude") )
方法二:用rnaturalearth获取更精准的质心
如果需要更官方的国家质心数据,可以通过国家边界计算质心:
# 安装必要包(首次使用时运行) # install.packages("rnaturalearth") # install.packages("sf") library(rnaturalearth) library(sf) # 获取世界国家地理数据 world_countries <- ne_countries(returnclass = "sf") # 计算每个国家的质心经纬度 world_centroids <- world_countries %>% mutate( lon = st_coordinates(st_centroid(geometry))[,1], lat = st_coordinates(st_centroid(geometry))[,2] ) %>% select(name, lon, lat) # 和你的数据合并(注意国家名称需匹配,若有不一致可手动调整) Team5 <- Team5 %>% ungroup() %>% left_join(world_centroids, by = c("Country" = "name"))
2. 计算国家间距离
根据你的需求选择对应的计算逻辑:
场景1:计算每行国家与指定基准国家的距离
比如以"Ireland"为基准,计算所有国家到它的距离(单位转成公里):
# 获取基准国家的经纬度 base_lon <- countrycode("Ireland", "country.name", "longitude") base_lat <- countrycode("Ireland", "country.name", "latitude") # 新增Distance列,处理NA值 Team5 <- Team5 %>% mutate( Distance = ifelse(is.na(lon) | is.na(lat), NA, distHaversine(cbind(lon, lat), c(base_lon, base_lat))/1000) )
场景2:计算每行与前一行国家的距离
如果需要计算相邻行国家之间的地理距离:
Team5 <- Team5 %>% mutate( # 提取前一行的经纬度 prev_lon = lag(lon), prev_lat = lag(lat), # 计算距离,NA情况返回NA Distance = ifelse(is.na(lon) | is.na(prev_lon), NA, distHaversine(cbind(lon, lat), c(prev_lon, prev_lat))/1000) ) %>% select(-prev_lon, -prev_lat) # 移除临时生成的列
3. 处理NA值
你的数据中有一行Country为NA,上述代码会自动将对应的Distance设为NA。如果需要进一步处理:
# 删除含NA的行 Team5_clean <- Team5 %>% filter(!is.na(Country)) # 或者将NA替换为0(按需调整) Team5 <- Team5 %>% mutate(Distance = replace_na(Distance, 0))
完整示例代码(基于countrycode方法,以Ireland为基准)
library(countrycode) library(geosphere) library(dplyr) # 取消分组 Team5 <- Team5 %>% ungroup() # 添加经纬度 Team5 <- Team5 %>% mutate( lon = countrycode(Country, "country.name", "longitude"), lat = countrycode(Country, "country.name", "latitude") ) # 设置基准国家 base_country <- "Ireland" base_lon <- countrycode(base_country, "country.name", "longitude") base_lat <- countrycode(base_country, "country.name", "latitude") # 计算距离并新增列 Team5 <- Team5 %>% mutate( Distance = ifelse(is.na(lon) | is.na(lat), NA, distHaversine(cbind(lon, lat), c(base_lon, base_lat))/1000) ) # 查看结果 head(Team5)
内容的提问来源于stack exchange,提问作者Soph2010
相关产品推荐
相关产品推荐

