在R中将普通数据框转为SpatialDataFrame?转换警告问题咨询
问题:将SpatialPointsDataFrame转普通数据框再转回sf对象时出现基准不一致警告
操作过程
- 原代码(来自Stack Overflow)成功制作交互式地图,使用的是
SpatialPointsDataFrame类型的city对象:
library(inlmisc) city <- rgdal::readOGR(system.file("extdata/city.geojson", package = "inlmisc")[1]) opt <- leaflet::markerClusterOptions(showCoverageOnHover = FALSE) map <- CreateWebMap("Topo") map <- leaflet::addMarkers(map, label = ~name, popup = ~name, clusterOptions = opt, clusterId = "cluster", group = "marker", data = city) map <- AddHomeButton(map) map <- AddClusterButton(map, clusterId = "cluster") map <- AddSearchButton(map, group = "marker", zoom = 15, textPlaceholder = "Search city names...") map
- 将
city转为普通数据框DF:
DF <- as.data.frame(city) > head(DF) name capital coords.x1 coords.x2 1 Abilene TX 0 -99.74 32.45 2 Akron OH 0 -81.52 41.08 3 Alameda CA 0 -122.26 37.77 4 Albany GA 0 -84.18 31.58 5 Albany NY 2 -73.80 42.67 6 Albany OR 0 -123.09 44.62
- 尝试用
st_as_sf转回空间数据框时出现警告:
Warning message: sf layer has inconsistent datum (+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs). Need '+proj=longlat +datum=WGS84
问题分析与修正
你的操作不完全正确。核心问题是:将SpatialPointsDataFrame转普通数据框时,丢失了原空间对象的坐标参考系(CRS)元数据,导致转回sf对象时系统无法识别正确的基准面(datum)。
原city对象是带WGS84(EPSG:4326)坐标参考系的空间数据,转普通数据框后仅保留了坐标数值,CRS信息完全丢失,这才触发了基准不一致的警告。
正确的转换流程
如果必须转为普通数据框处理后再转回空间对象,要手动保留CRS信息:
- 转换时保留坐标列和原CRS:
# 提取属性列+坐标列到数据框 DF <- cbind(as.data.frame(city), sp::coordinates(city)) # 保存原空间对象的CRS信息 crs_info <- sp::proj4string(city)
- 转回sf对象时指定正确的CRS:
library(sf) # 从数据框创建sf对象,指定坐标列和CRS sf_city <- st_as_sf(DF, coords = c("coords.x1", "coords.x2"), crs = crs_info)
更简洁的替代方案
直接用sf包读取原GeoJSON文件,跳过rgdal和SpatialPointsDataFrame的转换步骤,从根源避免CRS丢失问题:
library(sf) library(inlmisc) # 用sf直接读取GeoJSON,自动保留CRS信息 city <- st_read(system.file("extdata/city.geojson", package = "inlmisc")[1]) # 后续地图制作代码完全不变 opt <- leaflet::markerClusterOptions(showCoverageOnHover = FALSE) map <- CreateWebMap("Topo") map <- leaflet::addMarkers(map, label = ~name, popup = ~name, clusterOptions = opt, clusterId = "cluster", group = "marker", data = city) map <- AddHomeButton(map) map <- AddClusterButton(map, clusterId = "cluster") map <- AddSearchButton(map, group = "marker", zoom = 15, textPlaceholder = "Search city names...") map
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

