R terra包创建全年日长SpatRaster时rast函数运行报错
报错核心原因
rast(type = "xyz")的输入要求是覆盖整个研究区的所有格点坐标表,必须包含x(经度)、y(纬度)方向的完整坐标序列和对应属性值,才能自动推断栅格的范围、分辨率。你的代码里把x坐标全部固定为-100,只传入了单条经线上的纬度点,经度方向没有任何坐标变化,terra无法计算经度方向的格网间距,才会抛出invalid extent错误,同时触发no non-missing arguments to min的警告。- 原代码存在明显的效率冗余:日长仅和纬度、年积日(doy)相关,同一纬度下所有经度位置的日长值完全一致,不需要逐经度重复计算,逐列
cbind绑定数据的写法也会额外消耗大量内存。
修正实现代码
直接通过模板栅格固定空间参数,不需要手动构造全量xyz坐标表,运行效率远高于原循环写法:
library(geosphere) library(terra) # 生成0.5度分辨率的空间模板,固定范围、分辨率、坐标系 r_template <- rast( xmin = -180, xmax = 180, ymin = -60, ymax = 90, res = 0.5, crs = "EPSG:4326" ) # 提取模板所有格点的中心纬度值 lat_seq <- yFromRow(r_template, 1:nrow(r_template)) # 批量计算每个纬度对应366天的日长值,行对应纬度,列对应doy dl_matrix <- t(sapply(lat_seq, \(lat) daylength(lat, doy = 1:366))) # 按经度方向重复纬度日长值,生成和模板维度匹配的栅格数据矩阵 dl_rast_mat <- sapply(1:ncol(dl_matrix), \(col_idx){ rep(dl_matrix[, col_idx], each = ncol(r_template)) }) # 生成最终366层的SpatRaster对象 daylength_rast <- rast( dl_rast_mat, extent = ext(r_template), nrows = nrow(r_template), ncols = ncol(r_template), crs = crs(r_template) ) # 给图层按天命名 names(daylength_rast) <- paste0("day_", 1:366)
结果说明
- 输出的
daylength_rast完全符合需求:空间分辨率0.5度,坐标系为WGS84经纬度,共366个图层分别对应当年第1天到第366天的日长值,空间范围覆盖南纬60°至北纬90°的全部区域。 - 该实现避免了逐点重复计算,也不需要手动拼接坐标表,不会出现范围推断失败的问题,处理速度比原嵌套循环写法快数十倍。
内容的提问来源于stack exchange,提问作者JerryN
相关产品推荐
相关产品推荐

