使用spatstat创建像素图像对象遇阻:非矩形数据无法转矩阵
嘿,我来帮你搞定这个spatstat创建不规则区域像素图像的难题!你现在在研究雷击引发火灾的影响因素,却卡在了用im()函数生成像素图像这一步——你的研究区域是不规则形状,手里只有覆盖整个区域(包括边界和内部)的点数据,没法提取出多边形边界,之前试owin(poly=data)得到的是线而不是闭合区域,确实不是你想要的结果。下面针对你提出的两个思路给出具体的实现方案,再补充几个替代spatstat的栅格处理库选项:
其实spatstat里可以通过点数据的空间插值直接生成适配不规则区域的像素图像,不需要先转矩阵,步骤如下:
将数据转换为
ppp空间点模式对象
先把你的点数据转换成spatstat的核心对象ppp,同时用点的凸包自动生成适配的不规则窗口:library(spatstat) # 假设你的数据框名为df,包含lon、lat及elev等变量列 df_ppp <- ppp(x = df$lon, y = df$lat, window = convexhull.xy(df$lon, df$lat))插值生成像素图像
针对每个你要分析的变量(比如elev、slope),可以用插值方法生成对应窗口的像素图像。比如用克里金插值(适合连续变量):# 对elev变量进行克里金插值,生成像素图像 elev_im <- interp.im(df_ppp, df$elev, method = "krige")如果不需要复杂插值,也可以用简单的最近邻插值:
elev_im <- interp.im(df_ppp, df$elev, method = "nn")生成的
elev_im会自动匹配你用凸包创建的不规则窗口,完美适配你的研究区域。
如果一定要走矩形矩阵转im()的路线,可以按以下步骤操作:
确定覆盖区域的最小矩形范围
先从你的点数据中提取经纬度的极值,确定能包住整个不规则区域的最小矩形:x_min <- min(df$lon) x_max <- max(df$lon) y_min <- min(df$lat) y_max <- max(df$lat)生成矩形网格并补全缺失点
按照你需要的分辨率生成矩形网格的所有点,把原始数据和网格中缺失的点(即不在原始区域内的点)合并,缺失值设为NA:# 设置分辨率(参考你数据的间隔,示例数据中lon间隔约3.5) res <- 3.5 x_grid <- seq(x_min, x_max, by = res) y_grid <- seq(y_min, y_max, by = res) # 生成所有网格点 grid_df <- expand.grid(lon = x_grid, lat = y_grid) # 合并原始数据,匹配不上的变量填充NA merged_df <- merge(grid_df, df, by = c("lon", "lat"), all.x = TRUE)转矩阵并创建裁剪后的像素图像
把变量列转成矩阵,再创建im对象,最后裁剪回原始不规则区域:# 按纬度排序后转换为矩阵 merged_df <- merged_df[order(merged_df$lat, merged_df$lon), ] elev_matrix <- matrix(merged_df$elev, nrow = length(y_grid), ncol = length(x_grid)) # 创建矩形范围的im对象 elev_im <- im(elev_matrix, xrange = c(x_min, x_max), yrange = c(y_min, y_max)) # 裁剪回原始不规则区域 original_window <- convexhull.xy(df$lon, df$lat) elev_im_cropped <- crop.im(elev_im, original_window)最终的
elev_im_cropped就是只保留你研究区域的像素图像。
如果spatstat的操作对你来说太繁琐,这些专门的栅格处理库会更顺手:
raster库(经典栅格工具)
library(raster) # 创建空栅格 r <- raster(xmn = x_min, xmx = x_max, ymn = y_min, ymx = y_max, res = res) # 从点数据插值生成栅格 elev_raster <- rasterize(df[, c("lon", "lat")], r, df$elev, fun = mean) # 裁剪回不规则区域(需先将点转为凸包多边形) library(sf) original_poly <- st_as_sf(df, coords = c("lon", "lat")) %>% st_union() %>% st_convex_hull() elev_raster_cropped <- mask(elev_raster, original_poly)terra库(raster的高效升级版)
library(terra) # 创建空栅格 r <- rast(xmin = x_min, xmax = x_max, ymin = y_min, ymax = y_max, resolution = res) # 插值生成栅格 elev_terra <- rasterize(df[, c("lon", "lat")], r, df$elev) # 裁剪回不规则区域 original_poly <- vect(st_as_sf(df, coords = c("lon", "lat")) %>% st_union() %>% st_convex_hull()) elev_terra_cropped <- mask(elev_terra, original_poly)
内容的提问来源于stack exchange,提问作者Victor Taracena

