通过具有任意函数的非整数因子聚合栅格
Aggregate raster by a non-integer factor with arbitrary function
我想按 1.5 倍聚合人口栅格,对像元值求和。
虽然 aggregate()
允许我在聚合时对值求和,但它的 factor
参数只接受整数值。 projectRaster()
和 resample()
允许我精确调整分辨率,但(据我所知)我仅限于预先打包的双线性插值和最近邻计算方法。
有没有办法通过非整数因子聚合栅格并指定聚合时使用的函数?
library(raster)
set.seed(10)
proj <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
r <- raster(resolution = 1, nrow = 100, crs = proj)
r[] <- round(rnorm(ncell(r), 100, 10))
# Doesn't accept non-integer factors
aggregate(r, fact = 1.5, fun = sum)
template <- raster(extent(r), crs = crs(r), resolution = 1.5)
# Correct resolution, but incorrect / impossible values for population
projectRaster(r, to = template, method = "ngb")
projectRaster(r, to = template, method = "bilinear")
可能的解决方法
到目前为止,我能想到的唯一方法是将模板强制转换为 SpatialPoints
对象;从原始的高分辨率栅格中提取值; rasterize()
结果:
pts <- as(template, "SpatialPoints")
vals <- extract(r, pts)
pts2 <- SpatialPointsDataFrame(pts, data.frame(vals))
rasterize(pts2, template, field = "vals", fun = sum)
但是,如果点是在栅格像元的质心处创建的,我不确定在以原始栅格的 1.5 倍分辨率提取时如何处理它们。我的首选方法是创建一个 SpatialPolygonsDataFrame
并使用 fun = mean
进行栅格化,但是(根据我的经验)使用多边形提取栅格值的效率非常低。
这里有一个解决方法:
#first resample to higher resolution
template <- raster(extent(r), crs = crs(r), resolution = .5)
detailedRas <- projectRaster(r, to = template, method = "ngb")
#then use an integer as a factor (in this case 3)
aggRas <- aggregate(detailedRas, fact=3, fun=sum)
但请注意,在这种情况下,总和不会 return 居住在某个聚合区域的人数总和。
即:假设我们有四个单元格,这些值的分辨率为 1 米:
10 15
12 18
使用 NN 重采样到 0.5 后:
10 10 15 15
10 10 15 15
12 12 18 18
12 12 18 18
然后通过总和聚合到 1.5m 我们得到第一个像素:
10+10+15+10+10+15+12+12+18 = 112
虽然实际上它应该是这样的:
10 + 15/2 + 12/2 + 18/4 = 28(如果我们假设每个像素的人口分布相等。)
我建议使用带有自定义/用户定义函数的 focal
栅格函数来根据需要汇总人口值。
或者您将重采样栅格除以 4,然后求和:
2.5 2.5 3.75 3.75
2.5 2.5 3.75 3.75
3 3 4.5 4.5
3 3 4.5 4.5
2.5 + 2.5 + 3.75 + 2.5 + 2.5 + 3.75 + 3 + 3 + 4.5 = 28
我想按 1.5 倍聚合人口栅格,对像元值求和。
虽然 aggregate()
允许我在聚合时对值求和,但它的 factor
参数只接受整数值。 projectRaster()
和 resample()
允许我精确调整分辨率,但(据我所知)我仅限于预先打包的双线性插值和最近邻计算方法。
有没有办法通过非整数因子聚合栅格并指定聚合时使用的函数?
library(raster)
set.seed(10)
proj <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
r <- raster(resolution = 1, nrow = 100, crs = proj)
r[] <- round(rnorm(ncell(r), 100, 10))
# Doesn't accept non-integer factors
aggregate(r, fact = 1.5, fun = sum)
template <- raster(extent(r), crs = crs(r), resolution = 1.5)
# Correct resolution, but incorrect / impossible values for population
projectRaster(r, to = template, method = "ngb")
projectRaster(r, to = template, method = "bilinear")
可能的解决方法
到目前为止,我能想到的唯一方法是将模板强制转换为 SpatialPoints
对象;从原始的高分辨率栅格中提取值; rasterize()
结果:
pts <- as(template, "SpatialPoints")
vals <- extract(r, pts)
pts2 <- SpatialPointsDataFrame(pts, data.frame(vals))
rasterize(pts2, template, field = "vals", fun = sum)
但是,如果点是在栅格像元的质心处创建的,我不确定在以原始栅格的 1.5 倍分辨率提取时如何处理它们。我的首选方法是创建一个 SpatialPolygonsDataFrame
并使用 fun = mean
进行栅格化,但是(根据我的经验)使用多边形提取栅格值的效率非常低。
这里有一个解决方法:
#first resample to higher resolution
template <- raster(extent(r), crs = crs(r), resolution = .5)
detailedRas <- projectRaster(r, to = template, method = "ngb")
#then use an integer as a factor (in this case 3)
aggRas <- aggregate(detailedRas, fact=3, fun=sum)
但请注意,在这种情况下,总和不会 return 居住在某个聚合区域的人数总和。
即:假设我们有四个单元格,这些值的分辨率为 1 米:
10 15
12 18
使用 NN 重采样到 0.5 后:
10 10 15 15
10 10 15 15
12 12 18 18
12 12 18 18
然后通过总和聚合到 1.5m 我们得到第一个像素:
10+10+15+10+10+15+12+12+18 = 112
虽然实际上它应该是这样的: 10 + 15/2 + 12/2 + 18/4 = 28(如果我们假设每个像素的人口分布相等。)
我建议使用带有自定义/用户定义函数的 focal
栅格函数来根据需要汇总人口值。
或者您将重采样栅格除以 4,然后求和:
2.5 2.5 3.75 3.75
2.5 2.5 3.75 3.75
3 3 4.5 4.5
3 3 4.5 4.5
2.5 + 2.5 + 3.75 + 2.5 + 2.5 + 3.75 + 3 + 3 + 4.5 = 28