QGIS Labeling – How to Label the Highest Value Comparing Different Fields by Suffix Name

fields-attributeslabelingqgis

Based on a layer with point geometry with the following fields:

res_1_name

res_1_perc

res_2_name

res_2_perc

res_3_name

res_3_perc

How could I automate that the 'res_name' field that has the highest value in the 'res_perc' field is labeled with the value of the 'res_name' field.

I add a screenshot with the structure and values of a table, pointing out the value that should be tagged.

In this case it would be necessary to detect that the highest value (on fields 'res_1_perc', 'res_2_perc', 'res_3_perc') is 41.5 ('res_1_perc') and to tag the value OPTION1 ('res_1_name').

Style label:

OPTION1

41.5
enter image description here

Seeking a more open and simplified solution

The function proposed by the user JGH is a good solution, however, in the case of my project, there is the problem that I have to handle 10×10 fields (res_1_perc, res_2_perc, res_3_perc…, res_10_perc, res_1_name, res_2_name, res_name_3_name…, res_10_name).

The function would be as follows:

case
 WHEN res_1_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_1_name
 WHEN res_2_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_2_name
 WHEN res_3_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_3_name
 WHEN res_4_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_4_name
 WHEN res_5_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_5_name
 WHEN res_6_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_6_name
 WHEN res_7_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_7_name   
 WHEN res_8_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_8_name
 WHEN res_9_perc >= res_1_perc AND res_2_perc AND res_3_perc AND res_4_perc AND res_5_perc AND res_6_perc AND res_7_perc AND res_8_perc AND res_9_perc >= res_10_perc
   THEN res_9_nombre   
 ELSE res_10_name
END

I would like to ask for help to further refine the development of a function that simplifies the complexity of the previous function, as it could increase the number of fields in the attribute table.

My idea is to work with all the fields in the attribute table (no matter the number of fields), detecting the fields to process based on the field name suffix match.

I am working with the following function that tries to use the regexp_match function to solve this problem:

array_max(
    array_foreach(
        @layers ,
        array_length(
            if (
                regexp_match ("perc",'')),
                array()
))))

But this expression has now different problems (syntax, include field to tag res_*_name). Is it possible to use this approach from a correction of this expression?

Best Answer

Here is a completely generic solution. You can have as many fields as you like, but there should be no gaps in the given steps. Note that if there is more than one maxima, it will only pick the first one ordered by numeric fieldnames.

with_variable('vals',generate_series(1,3,1),
with_variable('percs',array_foreach(@vals,eval(concat('res_',@element,'_perc'))),
with_variable('names',array_foreach(@vals,eval(concat('res_',@element,'_name'))),

array_get(@names,array_find(@percs,array_max(@percs)))

)))

just change the values in generate_series(from,to,step) and the names of the fields if required.

Example result:

enter image description here