简体   繁体   English

带区域指令的加权平均计算

[英]Weighted mean calculation with zonal command

I'd like to know for each category, the weighted mean of a variable (as each pixel has a weight). 我想知道每个类别,变量的加权平均值(因为每个像素都有一个权重)。 The code below doesn't allow me to do weighted averages. 下面的代码不允许我做加权平均值。 Any suggestions would be greatly appreciated! 任何建议将不胜感激!

#sample rasters
    r <- raster(ncols=10, nrows=10)
    category <-  raster(ncols=10, nrows=10)
    weight <-  raster(ncols=10, nrows=10)
    r[] <- runif(ncell(r)) * 1:ncell(r)
    category[] <- runif(ncell(category)) * 1:ncell(category)
    weight[] <- 1:ncell(weight)

#mean for each category
    zonalstats <- zonal(r, z=category, fun='mean', digits=0, na.rm=TRUE, count=T)

you can use this function. 你可以使用这个功能。 It applies zonal to both the weights and the raster values and calculates the weighted mean. 它适用zonal的权重和栅格值都计算加权平均。

weightedZonalMean <- function(r, z, w, na.rm = TRUE, ...){
  zonalvalues <- zonal(r, z=z, fun=function(x, na.rm){x}, na.rm, ...)
  zonalweights <- zonal(w, z=z, function(x, na.rm){x},  na.rm, ...)
  weigtedValues <- cbind(zonalvalues[,1], 
                         sapply(1:nrow(zonalvalues), function(x){
    stats::weighted.mean(x = zonalvalues[x, 2:ncol(zonalvalues)], 
                         w = zonalweights[x, 2:ncol(zonalweights)])
  }))  
  return(weigtedValues)
}
weightedZonalMean(r, z, w, digits = 0)
#       [,1]      [,2]
#  [1,]    0 12.254438
#  [2,]    1  0.487548
#  [3,]    2  1.246249
#  [4,]    3 17.283858
#  [5,]    4 22.545906
#  [6,]    5 29.388179
#  [7,]    6 13.494853
#  [8,]    8  1.592464
#  [9,]    9 15.510155
# [10,]   10 10.091313
# ...

Unfortunately you can not do what you want with the zonal function, but you can build a similar function that calculates the weighted mean. 遗憾的是,您无法使用区域功能执行所需操作,但您可以构建一个计算加权平均值的类似函数。

If you run findMethods(zonal)$'RasterLayer#RasterLayer' you can see how the zonal function works, and by adapting it you can do a function like the one that solves your problem. 如果运行findMethods(zonal)$'RasterLayer#RasterLayer'您可以看到区域功能如何工作,通过调整它,您可以执行类似于解决问题的功能。

zonalWMean <- function(x, w , z, digits = 0, na.rm = TRUE) {

  if(!compareRaster(c(x, w, z))) error("Raster not comparable!")

  df <- data.frame(x = getValues(x),
                   w = getValues(w))
  zones <- round(getValues(z), digits = digits)

  dfs <- split(df, zones)
  out <- lapply(dfs, function(l) weighted.mean(l$x, l$w, na.rm = na.rm))
  out <- cbind(as.numeric(names(out)), out)
  colnames(out)[1] <- "zone"
  colnames(out)[2] <- "weighted.mean"

  return(out)
}
zonalWMean(r, weight, category)
   zone weighted.mean
0  0    4.685347     
1  1    3.251086     
2  2    55.33882     
3  3    4.384738     
4  4    25.26902     
5  5    28.34853     
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM