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

R中clhs函数传入sf点时报错‘Not a matrix’,是否为bug?

问题分析与解决

核心问题

你遇到的错误并非bug,而是clhs()处理sf对象时,需要明确指定用于抽样的数值属性变量,而非直接传入整个sf点对象。虽然文档说明支持sf输入,但实际需要确保函数能正确识别sf对象中的属性列作为分层依据。

具体修复步骤

  1. 检查sf对象结构
    你的smp是从栅格采样得到的sf点,属性表中仅包含树高这一数值列。clhs()需要基于这类数值属性完成分层抽样,所以要确保函数能访问到该属性。

  2. 两种可行修复方式

    • 方式一:提取sf对象的属性数据(剥离几何信息)传入,之后再从原始sf对象中匹配选中的样点
    • 方式二:直接传入sf对象,显式指定用于分层的属性列名

修复后的可运行代码

## 加载必要包
library(clhs)
library(terra)
library(sf)

## 可复现设置
set.seed(78)

## 创建模拟树高栅格
fake_rast <- rast(xmin=-123.5, xmax=123.0, ymin=44.5, ymax=45.0, nrow=200, ncol=200, crs="EPSG:4326")
values(fake_rast) <- rnorm(40000, 35, 10)

## 采样并转为sf对象
smp <- spatSample(fake_rast, 500, as.points=TRUE, na.rm=TRUE, replace=FALSE) %>% st_as_sf()

## 定义抽样参数
n <- 50
mi <- NULL
temp <- 100
lc <- 10
ol <- 0.01
td <- 0.9

## 修复方式1:提取属性矩阵,后续匹配原始样点
clhs.test1 <- clhs(x = st_drop_geometry(smp), size = n, temp=temp, 
                   iter=lc*log(ol/temp)/log(td), obj.limit=ol, tdecrease=td, 
                   length.cycle=lc, must.include=mi, use.cpp=TRUE, simple=FALSE)
# 获取选中的样点
selected_points1 <- smp[clhs.test1$index_samples, ]

## 修复方式2:直接传入sf对象,显式指定分层变量
clhs.test2 <- clhs(x = smp, size = n, temp=temp, iter=lc*log(ol/temp)/log(td), 
                   obj.limit=ol, tdecrease=td, length.cycle=lc, must.include=mi,
                   use.cpp=TRUE, simple=FALSE, vars = names(smp))
selected_points2 <- smp[clhs.test2$index_samples, ]

错误原因解释

  • 直接传入sf对象时,若clhs内部未正确识别属性列(部分版本对sf的支持存在细节兼容问题),会误判输入非数值矩阵,抛出Error: Not a matrix。
  • 用as.matrix()转换整个sf对象会包含几何信息(WKT格式文本),导致函数无法识别为有效数值输入,因此报错“不接受矩阵作为输入”。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:43:29