使用read_sf读取shp文件并合并为sf数据框失败,几何列呈列表格式
解决多个SHP文件合并为SF数据框的问题
我懂你这种头疼的情况——本来想把多个SHP文件合并成一个干净的sf数据框,结果搞出来的东西既不是sf对象,几何列还变成了乱糟糟的列表。别担心,这是因为你用了普通的行绑定方法,没照顾到sf对象的特殊空间属性,我来给你一步步解决这个问题!
问题根源
sf对象不是普通的数据框,它带有特殊的类属性和空间元数据(比如CRS、几何类型)。如果用dplyr::bind_rows这类通用行绑定函数,会丢失这些特殊属性,导致几何列退化成普通列表,结果也不再是sf对象。我们需要用sf专属的绑定工具来处理。
完整解决方案
下面是可复现的代码,从创建示例SHP文件到正确合并,一步到位:
1. 准备示例SHP文件(模拟你的数据源)
library(tidyverse) library(sf) # 用临时目录避免路径问题,你可以换成自己的目录 temp_dir <- tempdir() # 创建第一个sf数据框并导出为SHP data1 <- data.frame(attr = c(1:10), lon = c(11:20), lat = c(21:30)) %>% st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326) st_write(data1, file.path(temp_dir, "data1.shp"), delete_layer = TRUE) # 创建第二个sf数据框并导出为SHP data2 <- data.frame(attr = c(11:20), lon = c(21:30), lat = c(31:40)) %>% st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326) st_write(data2, file.path(temp_dir, "data2.shp"), delete_layer = TRUE)
2. 正确合并SHP文件
这里有两种简单可靠的方法,选你习惯的就行:
方法一:批量读取+合并一步完成(推荐)
用purrr::map_dfr,它会自动识别sf类并调用sf专属的合并逻辑:
# 获取目标目录下所有SHP文件的完整路径 shp_files <- list.files(temp_dir, pattern = "\\.shp$", full.names = TRUE) # 批量读取并直接合并为单个sf对象 combined_sf <- map_dfr(shp_files, st_read) # 验证结果:应该同时包含"sf"和"data.frame"类 class(combined_sf)
方法二:先读入列表再合并
如果你需要先对单个sf对象做一些预处理,这种方式更灵活:
# 把所有SHP文件读入一个sf对象列表 sf_list <- map(shp_files, st_read) # 用sf专属的st_bind_rows合并列表中的对象 combined_sf <- st_bind_rows(sf_list)
关键注意事项
- 统一CRS:确保所有待合并的SHP文件使用相同的坐标参考系,如果不同,先通过
st_transform()统一后再合并。 - 属性列兼容:如果各个SHP的属性列不一致,
st_bind_rows会自动填充缺失值为NA,同时保留sf对象的所有空间属性,这点和bind_rows行为一致,但更可靠。
内容的提问来源于stack exchange,提问作者adl
相关产品推荐
相关产品推荐

