R语言stars包读取ESA湖泊netCDF4文件时出现维度错误求助
问题描述
我从ESA湖泊气候变化倡议数据库下载了netCDF4文件,每个文件对应时间序列中的一天,包含表面温度、叶绿素a浓度等变量。计划用stars包完成两项操作:
- 地理子集筛选,仅保留目标湖泊区域
- 生成多变量的月度聚合时间序列
但处理时遇到两个核心问题:
- 调用
read_stars()读取文件时,直接抛出错误:Error in attr(x, "dimensions")[[along]] : subscript out of bounds,同时出现50+条警告 - 使用
read_ncdf()能读取文件,但坐标系识别异常,提示CRS无效。手动用st_set_crs(lake_2015_01_01_nc, 4979)修复后,文件仍为指向原netCDF4的代理对象,无法使用stars的各类数据操作函数
该文件在QGIS中可正常显示且地理配准正确,怀疑stars读取数据存在兼容性问题,需明确问题原因及解决方法。
复现代码如下:
library(stars) setwd() # 替换为实际文件路径 lake_2015_01_01 <- read_stars('ESACCI-LAKES-L3S-LK_PRODUCTS-MERGED-20150101-fv2.0.2.nc') # 对比read_ncdf函数的读取情况 lake_2015_01_01_nc <- read_ncdf('ESACCI-LAKES-L3S-LK_PRODUCTS-MERGED-20150101-fv2.0.2.nc')
问题原因分析
- read_stars()报错:ESA湖泊产品的netCDF文件采用了非标准的维度定义(如存在辅助维度、维度属性标记不符合stars默认解析规则),导致
read_stars()在解析维度时出现索引越界。 - read_ncdf()代理对象问题:
read_ncdf()默认生成懒加载的代理对象,仅保留对原文件的引用,未将数据加载到内存,因此无法执行stars的数据操作;同时文件自带的CRS元数据格式不符合stars的解析标准,导致CRS识别失败。
解决方法
方法1:将read_ncdf()代理对象转为内存stars对象
先通过read_ncdf()读取并修复CRS,再将代理对象转为内存中的stars对象,即可正常操作:
library(stars) # 读取指定变量(减少内存占用) nc_proxy <- read_ncdf( 'ESACCI-LAKES-L3S-LK_PRODUCTS-MERGED-20150101-fv2.0.2.nc', var = c('lake_surface_temperature', 'chlorophyll_a_concentration') # 替换为需要的变量 ) # 修复坐标系 nc_proxy <- st_set_crs(nc_proxy, 4979) # 转为内存stars对象 nc_stars <- as(nc_proxy, "stars")
方法2:用ncdf4预处理后手动构建stars对象
如果stars直接读取仍有问题,可借助ncdf4包读取数据,手动构建符合要求的stars对象:
library(stars) library(ncdf4) # 打开netCDF文件 nc <- nc_open('ESACCI-LAKES-L3S-LK_PRODUCTS-MERGED-20150101-fv2.0.2.nc') # 读取维度和变量数据 lon <- ncvar_get(nc, 'lon') lat <- ncvar_get(nc, 'lat') sst <- ncvar_get(nc, 'lake_surface_temperature') chla <- ncvar_get(nc, 'chlorophyll_a_concentration') # 关闭文件连接 nc_close(nc) # 构建stars对象 nc_stars <- st_as_stars( list( lake_surface_temperature = sst, chlorophyll_a_concentration = chla ), dimensions = st_dimensions( x = st_dimension(lon, name = "lon"), y = st_dimension(lat, name = "lat"), time = st_dimension(as.Date("2015-01-01"), name = "time") ) ) # 设置坐标系 st_crs(nc_stars) <- 4979
方法3:调整read_stars()参数适配文件结构
尝试指定read_stars()的sub参数,仅读取目标变量和维度,避免解析异常维度:
lake_stars <- read_stars( 'ESACCI-LAKES-L3S-LK_PRODUCTS-MERGED-20150101-fv2.0.2.nc', sub = c(lake_surface_temperature = 1, chlorophyll_a_concentration = 1), # 指定变量索引 quiet = TRUE # 屏蔽警告信息 ) # 修复坐标系 st_crs(lake_stars) <- 4979
内容的提问来源于stack exchange,提问作者Steven Brownlee
相关产品推荐
相关产品推荐

