Here’s my solution. I gave up with ArcGIS and QGIS, instead opting to output the data to file and perform the calculation in R.
# Load library
library(raster)
# Load chlorophyll data
chloro <- raster("../data/chloro.tif")
# Load polygons
poly <- shapefile("../data/poly.shp")
# Extract data in polygons
poly.chloro <- extract(chloro, poly)
# Determine proportion of polygon where there is specified proportion of data
poly.prop <- function(x, threshold){
foo <- approxfun(1 - cumsum(sort(x, na.last = NA))/sum(x, na.rm=TRUE), sort(x, na.last = NA))
return(sum(x - foo(threshold)>0, na.rm=TRUE)/length(x))
}
# Null array to hold threshold values
threshold.values <- NULL
# Loop through polygons
for(i in poly.chloro) threshold.values <- c(threshold.values, poly.prop(i, 0.8))
The above code determines the proportion of each polygon that is occupied by 80% of the total chlorophyll. Multiplying these proportions by the polygons’ area gives the area occupied by 80% of the chlorophyll, as required.
Initially, I load the raster
library, as well as the chlorophyll raster and polygon shape files. Next, I extract all of the raster points that are located in each polygon. The poly.prop
function performs the actual calculation. The raster values associated with each polygon are passed to this function, which sort
s them into ascending order. A cumulative sum of this sorted vector is calculated, which is then divided by the sum total of the vector. This gives the proportion of the total chlorophyll below each point in the sorted vector. For example, say at the n
th element of the vector has the value 0.2. This means that 20% of the chlorophyll is below that point. However, I’m phrasing my question in terms of how much is above that point, so I subtract that value from 1. (In my example, 1 - 0.2 = 0.8
means 80% is above that point.) Next, I use the approxfun
function to derive an empirical relationship between the values in the sorted vector (i.e., concentrations of chlorophyll) and the corresponding proportion of total chlorophyll above that point. This function takes a value, like 0.8, and returns the concentration of chlorophyll in the data set where there is 80% of the total chlorophyll above it. Finally, I subtract this threshold concentration from all of the raster values in that polygon and count how many raster values are above zero (i.e., above the threshold). When this is divided by the total number of raster values in that polygon, it gives the proportion of the polygon that is occupied by these points.
I'm not sure if that explanation is clear, but it works fine – I checked it against my initial rough method.
PS Thanks to everyone for your solutions and comments. This solution draws on several on the ideas presented by others above.