DataFrame转sf对象时geometry列异常的问题及解决方法
解决geometry列格式异常导致
st_sf报错的问题 我的tibble数据中,geometry列意外变为字符串类型(存储为类似list(c(...))的文本格式),此时调用st_sf函数会报错:no simple features geometry column present。
数据预览如下:
> head(double_early_1995, 20) # A tibble: 20 × 4 yield pattern year geometry <dbl> <chr> <chr> <chr> 1 4380. Double_Early 1995 list(c(117.2259, 117.2659, 117.2659, 117.2259, 117.2259, 31.5508, 31.5508, 31.5108, 31.5108, 31.5508)) 2 4691. Double_Early 1995 list(c(117.2659, 117.3059, 117.3059, 117.2659, 117.2659, 31.5508, 31.5508, 31.5108, 31.5108, 31.5508)) 3 3941. Double_Early 1995 list(c(117.3059, 117.3459, 117.3459, 117.3059, 117.3059, 31.5508, 31.5508, 31.5108, 31.5108, 31.5508)) 4 4286. Double_Early 1995 list(c(117.3459, 117.3859, 117.3859, 117.3459, 117.3459, 31.5508, 31.5508, 31.5108, 31.5108, 31.5508)) 5 4012. Double_Early 1995 list(c(117.1459, 117.1859, 117.1859, 117.1459, 117.1459, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 6 4413. Double_Early 1995 list(c(117.1859, 117.2259, 117.2259, 117.1859, 117.1859, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 7 3897. Double_Early 1995 list(c(117.2659, 117.3059, 117.3059, 117.2659, 117.2659, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 8 3857. Double_Early 1995 list(c(117.3059, 117.3459, 117.3459, 117.3059, 117.3059, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 9 3810. Double_Early 1995 list(c(117.3459, 117.3859, 117.3859, 117.3459, 117.3459, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 10 3787. Double_Early 1995 list(c(117.3859, 117.4259, 117.4259, 117.3859, 117.3859, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 11 3844. Double_Early 1995 list(c(117.9059, 117.9459, 117.9459, 117.9059, 117.9059, 31.5108, 31.5108, 31.4708, 31.4708, 31.5108)) 12 4281. Double_Early 1995 list(c(117.0659, 117.1059, 117.1059, 117.0659, 117.0659, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 13 3509. Double_Early 1995 list(c(117.1059, 117.1459, 117.1459, 117.1059, 117.1059, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 14 3704. Double_Early 1995 list(c(117.1459, 117.1859, 117.1859, 117.1459, 117.1459, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 15 4431. Double_Early 1995 list(c(117.1859, 117.2259, 117.2259, 117.1859, 117.1859, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 16 4532. Double_Early 1995 list(c(117.2259, 117.2659, 117.2659, 117.2259, 117.2259, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 17 3908. Double_Early 1995 list(c(117.2659, 117.3059, 117.3059, 117.2659, 117.2659, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 18 3839. Double_Early 1995 list(c(117.3059, 117.3459, 117.3459, 117.3059, 117.3059, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 19 3846. Double_Early 1995 list(c(117.3859, 117.4259, 117.4259, 117.3859, 117.3859, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708)) 20 3780. Double_Early 1995 list(c(117.4259, 117.4659, 117.4659, 117.4259, 117.4259, 31.4708, 31.4708, 31.4308, 31.4308, 31.4708))
解决方法
通过字符串解析将geometry列转换为sfc类型,具体代码如下:
double_early_1995 <- double_early_1995 %>% mutate(geometry = st_sfc(lapply(geometry, function(coords) { st_polygon(list(matrix(as.numeric(unlist(strsplit(substr(coords, 8, (nchar(coords) - 2)), ", "))), ncol = 2, byrow = F)))})))
代码逻辑说明:
substr(coords, 8, (nchar(coords) - 2)):去除字符串开头的list(c(和结尾的)),提取纯坐标文本strsplit(..., ", "):按逗号分割坐标文本为单个字符串元素unlist()+as.numeric():将分割后的列表转为数值型向量matrix(..., ncol=2, byrow=F):将数值向量转为2列矩阵(对应经度、纬度)st_polygon(list(...)):将矩阵转为多边形几何对象lapply()+st_sfc():对每行geometry文本执行转换,最终生成sfc类型的几何列
内容的提问来源于stack exchange,提问作者Yabin Da
相关产品推荐
相关产品推荐

