3

Is there a was to use graduated symbology and have it calculate and classify the data by percentile?

I'd like to group my data in the following percentiles:

0-25 %
25-50 %
50-85 %
85-100 %
1

2 Answers 2

4

You can use Categorized styling with an expression.

My field with values is named field1

CASE 
    WHEN "field1"< (25*( count( "field1")+1))/100 THEN '0-25 %'
    WHEN "field1" BETWEEN (25*( count( "field1")+1))/100 AND (50*( count( "field1")+1))/100  THEN '25-50 %'
    WHEN "field1" BETWEEN (50*( count( "field1")+1))/100 AND (85*( count( "field1")+1))/100  THEN '50-85 %'
    WHEN "field1" BETWEEN (85*( count( "field1")+1))/100 AND (100*( count( "field1")+1))/100 THEN '85-100 %'
    ELSE 'ERROR'
END

enter image description here

1
  • This is an elegant solution but I think it applies only to one special case: when "Field1" contains a set of inverse-ranked values from 1 to n (n being the number of records, n being largest rank and 1 being smallest). In any other case, one can imagine situations where all values fell into the "0-25%" category or that some or all fall into the "ERROR" category (e.g assuming 100 records, any value above 101 would be so). It would be awesome if this could be generalized to apply to any set of numbers by somehow doing the ranking first or using percentiles as the case limits. Commented Aug 11, 2023 at 22:10
3

Here is a generalized solution inspired by (aka largely stolen from) this answer by @MrXSquared here: Make "quantile" classification with an expression

with_variable(
    'percentile',
    array_find(array_agg("field1",order_by:="field1"),"field1") / array_length(array_agg("field1")),
    CASE
        WHEN @percentile <= 0.25 THEN '0-25%'
        WHEN @percentile <= 0.5 THEN '25-50%'
        WHEN @percentile <= 0.75 THEN '50-75%'
        WHEN @percentile <= 1 THEN '75-100%'
        ELSE 'Undefined'
    END
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.