You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在terra中为各层因子水平不同的rast栈设置统一因子水平

问题描述

我有一个terra::rast()格式的连续数据栅格栈,需要将其分类为n个类别、转换为因子后进行离散尺度绘图。但遇到一个问题:当第一个栅格不包含其他栅格具备的全部因子(比如只含3个分类值,而非转换后的完整因子集合)时,绘图会异常。我希望能让栅格栈(或绘图函数)识别到:整个栈的因子水平是该栈的最小-最大值范围,部分层可能缺少部分水平。有意思的是,如果第一层包含所有可能的类别/因子,后续层的绘图就能正常显示。

# 模拟数据
library(terra)
r1 <- rast(nrows = 10, ncols = 10, xmin = 0, xmax = 10, ymin = 0, ymax = 10)
r1[] <- runif(ncell(r1), min = 1, max = 5)  # 生成1到5之间的随机值

r2 <- rast(nrows = 10, ncols = 10, xmin = 0, xmax = 10, ymin = 0, ymax = 10)
r2[] <- runif(ncell(r2), min = 1, max = 5)

# 合并栅格为栈
s <- c(r1/r1, r1/r2, r2/r1, r2/r2)
names(s) <- c("r1/r1", "r1/r2", "r2/r1", "r2/r2")

# 重分类栅格栈
# 定义重分类矩阵
m_rc <- matrix(c(0, 0.5, 1, 
                 0.5, 0.9, 2, 
                 0.9, 1.1, 3,
                 1.1, 2, 4,
                 2, max(global(s, max, na.rm=T)$max), 5), 
               ncol = 3, byrow = TRUE)

# 应用重分类
s_r <- classify(s, m_rc)

# 将重分类后的栅格转换为因子,用于分类绘图
s_r_f <- as.factor(s_r)

# 使用ggplot2和tidyterra绘图,并自定义图例标签
ggplot() +
  geom_spatraster(data = s_r_f) +
  facet_wrap(~lyr, nrow = 2) +  # 每层单独绘图
  scale_fill_manual(
    values = c("blue","lightblue" , "white", "yellow", "red"),  # 自定义颜色
    na.value = "transparent",    # NA值设为透明
  ) +
  labs(
    title = "重分类栅格栈",
    labels = c("0 - 0.5","0.5 - 0.9","0.9 - 1.1","1.1 - 2","> 2"),
    fill = "类别"
  ) +
  theme_minimal()
解决方案

问题核心是as.factor(s_r)默认会为每个栅格层单独提取自身的唯一值作为因子水平,导致各层因子水平不统一。要解决这个问题,需要手动指定整个栅格栈的完整因子水平,确保所有层使用相同的因子定义:

  • 统一因子水平:在转换为因子时,明确指定levels参数为所有可能的分类值(即重分类后的1到5),同时绑定对应的标签:
# 定义完整的因子水平和对应标签
factor_levels <- 1:5
factor_labels <- c("0 - 0.5","0.5 - 0.9","0.9 - 1.1","1.1 - 2","> 2")

# 转换为因子时强制使用统一的水平和标签
s_r_f <- as.factor(s_r, levels = factor_levels, labels = factor_labels)
  • 调整绘图代码:此时因子本身已带有标签,scale_fill_manual无需重复设置labels参数,直接使用统一的颜色映射即可:
ggplot() +
  geom_spatraster(data = s_r_f) +
  facet_wrap(~lyr, nrow = 2) +
  scale_fill_manual(
    values = c("blue","lightblue" , "white", "yellow", "red"),
    na.value = "transparent"
  ) +
  labs(
    title = "重分类栅格栈",
    fill = "类别"
  ) +
  theme_minimal()

这样处理后,即使部分栅格层缺少某些分类值,绘图时仍会保留完整的图例,所有层使用统一的颜色映射,彻底解决绘图异常问题。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:16:13