如何将fortified data.frame转回sf对象?以fiftystater包为例
把Fortified数据框转成sf多边形对象(以fiftystater包为例)
嘿,这个需求我之前碰到过,刚好可以给你详细说下怎么操作——不管是fifty_states这个特定数据,还是其他强化(fortified)的数据框,都可以用这套思路转成sf对象,然后用geom_sf绘图。
核心思路
Fortified数据框是ggplot2早期用来处理空间数据的格式,本质是把多边形拆成了一个个坐标点,带long/lat(坐标)、group(多边形部件分组)、hole(是否为多边形的洞)这些字段。要转成sf,核心就是把同一组的点重新组合成多边形,再处理洞的逻辑。
具体操作步骤
1. 加载依赖包
首先得把需要的包装上并加载:
library(fiftystater) library(sf) library(dplyr) library(stringr) # 用来处理group字段的字符串
2. 转换fifty_states为sf对象
直接上代码,每一步都加了注释:
# 第一步:按group分组,把每个部件转成单个多边形 state_parts <- fifty_states %>% group_by(group) %>% summarise( # 把long/lat转成矩阵,再用st_polygon创建多边形 geometry = st_polygon(list(cbind(long, lat))), # 保留hole标记,后续处理洞用 hole = first(hole), # 提取州的id(从group里去掉后面的.数字) id = first(str_remove(group, "\\.\\d+$")) ) %>% ungroup() # 第二步:把同一州的主多边形和洞组合成MultiPolygon fifty_states_sf <- state_parts %>% group_by(id) %>% summarise( geometry = st_multipolygon(list( # 主多边形:取hole=FALSE的部件 geometry[!hole][[1]], # 洞:把hole=TRUE的部件收集起来,sf要求洞的坐标方向和主多边形相反(fortified数据一般已经处理好了) lapply(geometry[hole], function(x) x[[1]]) )) ) %>% # 转换成sf对象 st_sf()
3. 用geom_sf绘图验证
现在就可以用熟悉的ggplot2 + geom_sf来画图了:
library(ggplot2) ggplot(fifty_states_sf) + geom_sf(aes(fill = id), color = "white", linewidth = 0.2) + scale_fill_viridis_d(option = "plasma") + theme_minimal() + theme(legend.position = "none")
通用转换方法(适用于任何fortified数据框)
如果以后碰到其他强化的数据框,都可以按这个流程来:
- 找到分组字段:通常是
group,每个组对应一个多边形的单个部件(主多边形或洞) - 按分组聚合,把
long/lat转成矩阵,用st_polygon创建单个多边形 - 如果有
hole字段,按父ID(比如这里的id)分组,把主多边形和洞组合成MultiPolygon - 最后用
st_sf()转换成sf对象
小提示:如果你的fortified数据没有自动闭合(第一个点和最后一个点不同),可以在聚合前给每个组添加一行第一个点的坐标,保证多边形闭合。
内容的提问来源于stack exchange,提问作者sebdalgarno
相关产品推荐
相关产品推荐

