R语言栅格数据建模分析标准套路,结构方程模型、偏最小二乘路径模型、冗余分析、典范对应分析等等等等都可以遵循这个套路

学术   科学   2024-12-23 18:01   云南  

有同学问如何使用栅格数据做冗余分析(Redundancy Analysis, RDA),对于这种情况和类似的情况,可以参考以前分享的一篇论文:JCP|利用结构方程模型量化自然和人为因素对植被变化的影响。中国江苏省的一个案例研究,这篇论文是使用栅格和其他的多源数据做的结构方程模型,其实方法是类似的,在这里我给大家总结成了下图的标准套路:

R语言多源栅格数据模型分析标准套路

基于R语言的多源栅格数据的标准套路大约分为五个步骤:

  1. 数据输入,读取多源数据
  2. terra包栅格裁剪、重采样、波段合成、转数据框、数据提取等:
  • 对数据进行裁剪、重采样,由于多源数据的空间范围和分辨率可能不一致,在后续处理前最好是将空间范围和分辨率进行统一。在这里使用的是terra包,涉及函数有:裁剪trim(mask()),重采样resample()
  • 波段合成:多源数据往往来自于多个TIF,为了方便后续的分析处理,可以使用中括号[]c()函数进行波段选择与波段合成,将待分析的多源栅格数据组合成一个多波段的SpatRaster,方便后续的处理
  • 栅格数据转面板数据,可以使用terra::as.data.frame()将所有的像元值转为数据框,或者extract()将像元值提取到采样点,或者zonal()分区统计等等
3. 数据清洗,步骤2已经将栅格转为面板属性数据,这里就可以使用tidyverse来完成了,比如去除空缺值、长宽数据转换等,将数据转换为模型输入所需的
 4. 统计建模,这一步就可以使用各种模型进行分析了,具体需要看各个模型的介绍
  1. 可视化,对建模结果进行可视化,得到分析结果


多源栅格数据进行模型分析的标准套路

栅格数据结构方程模型实例代码

下面给出使用栅格数据进行结构方程模型的实例代码,方法基本和前面提到的论文一致。

下面的代码符合前面的标准流程:

  1. 读取多源栅格
  2. terra包数据提取
  3. tidyverse数据清洗
  4. SEM建模
  5. 可视化结构方程模型结果

需要注意的是,下面的实验结果是失败的,未达到预期目标。但是流程跑通了,把代码开放出来供大家学习参考。这种情况下就需要调整输入数据或者修改、更换模型方法,直到实验成功为止。

采样点生成可以参考下面的视频号:

代码全文:
#读取裁剪好的Sen+Mk结果
sggrowym_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/sggrowym_senmk_MM.tif")
tmpgrowym_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/tmpgrowym_senmk_MM.tif")
pregrowym_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/pregrowym_senmk_MM.tif")
sradgrowym_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/sradgrowym_senmk_MM.tif")
aetgrowym_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/aetgrowym_senmk_MM.tif")
soilgrowym_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/soilgrowym_senmk_MM.tif")
NTL_senmk_MM = rast("D:/Mongolia/NDVIClimExport/MMndviclim/Sen+MK/NTL_senmk_MM.tif")

#读取样本点
SP_Mo = vect("./ROI.gpkg", query = 'SELECT * FROM SP_Mo')
SP_Mo
SP_CN = vect("./ROI.gpkg", query = 'SELECT * FROM SP_CN')
SP_CN

#提取点对应的高程、起伏度、坡度、坡向值
CopDSM_Mo = terra::extract(CopDSM, SP_Mo)
CopDSM_CN = terra::extract(CopDSM, SP_CN)
#光热因子
Srad_Mo = terra::extract(sradgrowym_senmk_MM[["slope"]], SP_Mo)
Srad_CN = terra::extract(sradgrowym_senmk_MM[["slope"]], SP_CN)
Tmp_Mo = terra::extract(tmpgrowym_senmk_MM[["slope"]], SP_Mo)
Tmp_CN = terra::extract(tmpgrowym_senmk_MM[["slope"]], SP_CN)
#水分因子
Pre_Mo = terra::extract(pregrowym_senmk_MM[["slope"]], SP_Mo)
Pre_CN = terra::extract(pregrowym_senmk_MM[["slope"]], SP_CN)
Aet_Mo = terra::extract(aetgrowym_senmk_MM[["slope"]], SP_Mo)
Aet_CN = terra::extract(aetgrowym_senmk_MM[["slope"]], SP_CN)
Soil_Mo = terra::extract(soilgrowym_senmk_MM[["slope"]], SP_Mo)
Soil_CN = terra::extract(soilgrowym_senmk_MM[["slope"]], SP_CN)
#夜间灯光
NTL_Mo = terra::extract(NTL_senmk_MM[["slope"]], SP_Mo)
NTL_CN = terra::extract(NTL_senmk_MM[["slope"]], SP_CN)

#NDVI
NDVI_Mo = terra::extract(sggrowym_senmk_MM[["slope"]], SP_Mo)
NDVI_CN = terra::extract(sggrowym_senmk_MM[["slope"]], SP_CN)

#将各种参数汇总
library(tidyverse)
SEMdata_Mo = Popslope_Mo %>% 
  left_join(CopDSM_Mo, by = c("X"="ID")) %>% 
  left_join(Srad_Mo, by = c("X"="ID")) %>% 
  left_join(Tmp_Mo, by = c("X"="ID")) %>% 
  left_join(Pre_Mo, by = c("X"="ID")) %>% 
  left_join(Aet_Mo, by = c("X"="ID")) %>% 
  left_join(Soil_Mo, by = c("X"="ID")) %>% 
  left_join(NTL_Mo, by = c("X"="ID")) %>% 
  left_join(NDVI_Mo, by = c("X"="ID")) %>% 
  set_names(c("ID""Lat""Lon""Pop""Ele""Relief""Aspect""Slope""Srad""Tmp""Pre""Aet""Soil""NTL""NDVI"))

SEMdata_CN = Popslope_CN %>% 
  left_join(CopDSM_CN, by = c("X"="ID")) %>% 
  left_join(Srad_CN, by = c("X"="ID")) %>% 
  left_join(Tmp_CN, by = c("X"="ID")) %>% 
  left_join(Pre_CN, by = c("X"="ID")) %>% 
  left_join(Aet_CN, by = c("X"="ID")) %>% 
  left_join(Soil_CN, by = c("X"="ID")) %>% 
  left_join(NTL_CN, by = c("X"="ID")) %>%
  left_join(NDVI_CN, by = c("X"="ID")) %>% 
  set_names(c("ID""Lat""Lon""Pop""Ele""Relief""Aspect""Slope""Srad""Tmp""Pre""Aet""Soil""NTL""NDVI"))
#输出结构方程模型所需数据
# write.csv(SEMdata_Mo, file = "D:/Mongolia/NDVIClimExport/SEMdata/SEMdata_Mo.csv")
# write.csv(SEMdata_CN, file = "D:/Mongolia/NDVIClimExport/SEMdata/SEMdata_CN.csv")

library(lavaan)
# 创建SEM模型语法
model <- '
  # 指定潜在变量
  # 定义植被变化
    Vegetation =~ NDVI
    #定义地理、气候、人类活动影响因子
    ClimFactor =~ Pre + Aet + Soil + Srad + Tmp
    GeoFactor =~ Lat + Lon + Ele + Relief + Aspect + Slope
    HumanFactor =~ Pop + NTL

  # 指定直接效应
    Vegetation ~ ClimFactor + GeoFactor + HumanFactor

  # 指定误差项
    Pre ~~ Tmp
    Pre ~~ Aet
    Pre ~~ Soil
    Pre ~~ Srad
    Pop ~~ NTL
'


# 拟合模型
fit <- sem(model, data = SEMdata_CN)

summary(fit)

# 使用 fitMeasures 获取标准误差
se <- fitMeasures(fit, c("satorra.bentler.scaled""rmsea""srmr"))
print(se)

semPlot::semPaths(fit, "std",residuals=F,nCharNodes=4,layout="tree2",edge.label.cex = 1,sizeMan =5)
第二步、第三步,栅格转面板数据清洗后的结果
第四步,结构方程模型建模结果
第五步,可视化结果,这是一个失败的结构方程模型

相关阅读

  1. JCP|利用结构方程模型量化自然和人为因素对植被变化的影响。中国江苏省的一个案例研究
  2. QGIS生成随机样点并提取栅格像元值
  3. 基于栅格数据计算重心转移模型——以NDVI重心转移为例
  4. R语言terra包栅格数据处理基础操作与技巧详解
  5. R语言栅格时间序列回归分析——整体和逐像元计算,并行计算,快到飞起!

更多R语言栅格数据处理课程请点击阅读原文扫码加入地理数据科学培训班

走天涯徐小洋地理数据科学
一个爱生活的地理土博,分享GIS、遥感、空间分析、R语言、景观生态等地理数据科学实操教程、经典文献、数据资源
 最新文章