R语言中使用extract()计算缓冲区值为1的像素占比问题
解决R语言raster包extract函数计算缓冲区1像素占比的问题
我来帮你修复这个问题,你的自定义函数perc1的逻辑存在一处错误,导致无法正确统计值为1的像素占总像素(含NA)的百分比。下面是具体的分析和解决方案:
问题根源
你的perc1函数中,leng1<-length(values(x) ==1)这行代码逻辑有误:
values(x) ==1会生成一个与缓冲区像素数量等长的逻辑向量,每个元素对应像素是否等于1length()返回的是这个逻辑向量的总长度,而非其中TRUE的数量,这就导致你计算的百分比永远是100%,完全不符合预期。
修正后的完整方案
步骤1:修正自定义统计函数
我们需要用sum()来统计值为1的像素个数,同时保留总像素数(含NA)的计算逻辑,还需要处理缓冲区无像素的极端情况避免报错:
perc1 <- function(x, ...) { # 统计缓冲区中值为1的像素数量(忽略NA,因为NA不是目标值) count_1 <- sum(x == 1, na.rm = TRUE) # 统计缓冲区总像素数(包含所有NA和非NA像素) total_pixels <- length(x) # 计算百分比,保留两位小数;若总像素为0则返回NA避免除以0报错 perc <- ifelse(total_pixels == 0, NA, round((count_1 / total_pixels) * 100, 2)) return(perc) }
步骤2:完整运行代码并合并结果
将修正后的函数代入你的原有代码流程,最后合并提取结果与原始坐标数据框,得到你期望的输出格式:
# 加载必要包 library(raster) # 创建示例栅格数据 set.seed(0) ras <- raster(ncol=1000, nrow=1000) values(ras) <- runif(ncell(ras)) values(ras)[values(ras) > 0.5] = 1 values(ras)[values(ras) < 0.5] = NA # 创建坐标点数据框 pts <- sampleRandom(ras, size=30, xy=TRUE) pts.df <- as.data.frame(pts) pts.df$area <- rnorm(30, mean=10) # 提取缓冲区的1像素占比 cent_max <- raster::extract(ras, cbind(pts.df$x, pts.df$y), buffer = 100000, fun = perc1, df = TRUE) # 合并结果到原始数据框 result_df <- cbind(pts.df, percentual_1s = cent_max$layer) # 查看前6行结果 head(result_df)
预期输出
运行后你会得到类似如下的结果,完全符合你的需求:
x y layer area percentual_1s 1 -109.26 -43.65 1 10.349010 23.15 2 93.42 -87.21 1 9.861920 45.18 3 57.06 86.85 1 8.642071 74.32 4 -109.98 -45.63 1 10.376485 11.56 5 -92.34 37.89 1 10.375138 56.89 6 19.62 21.51 1 8.963949 88.15
内容的提问来源于stack exchange,提问作者Leprechault
相关产品推荐
相关产品推荐

