# Shanon diversity index in QGIS

I'm trying to calculate Shannon diversity index for trees in a urban context. I have the following attribute table which I got joining attributes by location between a vector points and a vector grid. The field "res" has the tree species from the point layer. The field "id_malla" has the grid identifier ("id malla" means grid ID in Spanish).

I got the field "act_tot_id" by counting total number of points in every grid cell with the expression:

count("res", "id_malla")


I got the field "act_div_id", which is the number of species by each cell code, by the field calculator with this expression:

count_distinct(“res”, “id_malla”)


The issue comes when I try to calculate the number of individuals within each species by cell code ("id_malla"). I've tried several times with many combinations but I can't get the result. Here are a few of the expressions I've tried:

count("res", "act_tot_id", "id_malla")
count("res", "id_malla", "act_div_id")
count("res", "res", "act_div_id")


None of these gives any proper result

Can someone help with this?

The syntax for the count function is as follows:

count(expression[,group_by][,filter])

As you can see, it accepts one group_by input.

The methods you've tried all had three inputs. The third input will always be interpreted as a filter parameter, not as a second group_by parameter.

Instead, you need to combine the two fields ("act_tot_id" and "id_malla") into a single group_by expression. Try this:

count("res", concat(to_string("act_tot_id"),to_string("id_malla")))


Update: The above expression did not work, but Rodrigo Vargas was able to solve the problem by creating a new field with "act_tot_id" and "id_malla" concatenated, and running the count on the concatenated field. See their answer for the correct expression.

• It doesn't work, it returns values above expected. But I think the solution can come by concatenating fields as well. I'll keep on trying. – Rodrigo Vargas Jun 6 at 20:56
• Good luck. If you can't get it to work by concatenation, you can do it slowly by selecting all the points in one grid square, and updating only the selected features with count("res", "act_tot_id"). Then repeat for each grid square. Or try without the to_string() conversion, and combine the numerical fields arithmetically, like count("res", "act_tot_id"+100*"id_malla"). The goal is to combine the two field values so that each combination has a unique value. – csk Jun 6 at 21:04
• Done! First I creted a field concatenating "res" || '_' || "id_malla" and then count("res", "concat") Thanks, your clue led to the solution :) Anyway I guess there should be a cleaner way... – Rodrigo Vargas Jun 6 at 21:36
• I'm glad you figured it out. I'm not sure why it works when you put the concatenation in a separate field but not with concatenating inside the count() function, but the important thing is that it does work. Please change your "accepted" mark to your own answer to anyone who has a similar question gets directed to the correct answer (if I remember correctly, the website might make you wait a day or so to accept your own answer). – csk Jun 7 at 16:52
• I don't know either, maybe it's due to my lack of experience. I Tried many times but it didn't work, always returning the first code followed by underscore missing the second code. Thanks again for your help – Rodrigo Vargas Jun 11 at 13:34

Finally I arrived to a solution creating the field "concat" by concatenating in a single string:

"res" || '_' || "id_malla"


Then in the field calculator:

count("res", "concat")


Now there's only left to calculate the index by the formula:

H' = sum( "Pi" / ln(2, "Pi") ) * -1


where

Pi = "act_n_cd" / "act_tot_id"
`

for each grid cell