R语言如何将经纬度长度不同的大型列表转换为栅格或数据框
Levitus海表盐度数据转规整数据框方法
数据结构说明
levitus是oce生态常用的压缩网格存储格式,没有显式存储每一组经纬度对应的盐度值,三个核心元素的对应关系为:
levitus$longitude:长度360的经度向量,精度1°,范围0°~359°,对应盐度矩阵的列维度levitus$latitude:长度180的纬度向量,精度1°,范围-89.5°~89.5°,对应盐度矩阵的行维度levitus$SSS:180行×360列的数值矩阵,第i行第j列的值,对应第i个纬度、第j个经度格点的海表盐度,陆地区域填充值为NA
转换方法
方法1:Base R 原生实现(无额外依赖)
不需要安装第三方数据处理包,直接通过网格生成+矩阵拉直完成转换:
# 安装依赖包(首次运行执行) install.packages(c("oce", "ocedata")) # 加载数据 data(levitus, package = "ocedata") # 生成所有经纬度网格组合 sss_df <- expand.grid( longitude = levitus$longitude, latitude = levitus$latitude ) # 按列拉直SSS矩阵,匹配网格顺序赋值 sss_df$SSS <- as.vector(levitus$SSS) # 可选步骤:移除陆地区域的NA值,压缩数据体积 sss_df <- na.omit(sss_df)
方法2:tidyverse 实现
如果习惯用tidyverse语法处理数据,可以用宽转长的方式实现:
library(tidyverse) # 加载数据 data(levitus, package = "ocedata") sss_df <- levitus$SSS |> as.data.frame() |> # 列名设置为对应经度值 set_names(levitus$longitude) |> # 新增纬度列 mutate(latitude = levitus$latitude) |> # 宽表转长表,得到规整的三列结构 pivot_longer( cols = -latitude, names_to = "longitude", values_to = "SSS", names_transform = as.numeric ) |> # 过滤陆地区域缺失值 drop_na(SSS)
效果验证
转换后得到的sss_df是标准data.frame结构,三列分别为经度、纬度、海表盐度值,可以直接传入ggplot2自定义绘图,不需要依赖oce内置的imagep封装函数,例如下述代码的渲染效果和oce内置绘图的网格对应关系完全一致:
library(ggplot2) ggplot(sss_df, aes(x = longitude, y = latitude, fill = SSS)) + geom_raster() + scale_fill_viridis_c(name = "海表盐度") + coord_quickmap()
注:如果需要转换为-180°~180°范围的经度,只需要新增一列做换算即可:
sss_df$longitude <- ifelse(sss_df$longitude > 180, sss_df$longitude - 360, sss_df$longitude)
内容的提问来源于stack exchange,提问作者Ryan Utz
相关产品推荐
相关产品推荐

