3

already read many answers for similar questions, but i didnt find a solution for my problem. Dont know how to start.

Problem: shp with about 50 fields. Each field contain NULL, 1 or 2. Now i need two new fields. One containing the number of fields with "1", the other with "2".

I am using QGis 2.16.2 and 2.14; OS Win10

I'm trying @Joseph's solution, add the hint @kyle reed and make some modifications to start as an expression:

@qgsfunction(args='auto', group='Custom')
def R1func(feature, parent):
    lists = []
    layer = qgis.utils.iface.activeLayer()
    for feat in layer.getFeatures():
        f = feat.fields()
        num = f.count()
        for i in range(num):
             if feat[i] == 2:
                 lists.append(i)

    return len(set(lists))

and also try a short version

@qgsfunction(args='auto', group='Custom')
def R2func(feature, parent):
    lists = [] 
    layer = qgis.utils.iface.activeLayer()
    for feat in layer.getFeatures(): 
        lists.append(feat.fields())

    return lists.count(2)

Version 1 returns for every row 60 (for number 1) or 37 (for number 2) Version 2 returns 0

Maybe i make a mistake.

2
  • 3
    QGIS version? OS? Personally I would do this in Excel, export to CSV, import in QGIS and then join. Sep 23, 2016 at 9:43
  • Welcome to gis.stackexchange! Please note that a good question on this site is expected to show some degree of research on your part, i.e. what you have tried and - if applicable - code so far. For more info, you can check our faq.
    – underdark
    Sep 23, 2016 at 17:16

2 Answers 2

4

Using a bit of python, you could obtain the number of fields which contains a specific value. Use the following in the Python Console and change the value:

lists = []
layer = iface.activeLayer()  
for feat in layer.getFeatures():
    f = feat.fields()
    num = f.count()
    for i in range(num):
        # Look for fields with a value of 1
        if feat[i] == 1:
            lists.append(i)

print len(set(lists))

Then use the printed value as the expression when adding a new field. Repeat for your second value.


EDIT:

If you want to count the values in each row, you could use the following in the Function Editor of the Field Calculator:

from qgis.core import *
from qgis.gui import *
import qgis

@qgsfunction(args='auto', group='Custom')
def counting(value1, feature, parent):
    layer = qgis.utils.iface.activeLayer()
    return feature.attributes().count(value1)

Then type as the expression:

counting(1)

This will count all values which equal 1 for each row in each field.


Note that if you use it twice, it will also count the values in the new field that was created previosuly, in which case you would have to subtract all values greater than zero by one.

8
  • ok, get the error "name 'iface' is not defined"
    – S.Wiwa
    Sep 23, 2016 at 16:21
  • not completly understand your code. isnt it twice the same? Doesnt the function count already return the number in an array? lists = [] layer = iface.activeLayer() for feat in layer.getFeatures(): lists.append(feat.fields()) print lists.count(1)
    – S.Wiwa
    Sep 23, 2016 at 16:33
  • i'd put the code into the question
    – S.Wiwa
    Sep 23, 2016 at 18:13
  • @S.Wiwa - Does each field only contain one value? E.g. All rows in "Field_X" only has a value of 1. Or do fields contain more than one value? The code I posted only assumes that each field contains one constant value.
    – Joseph
    Sep 27, 2016 at 11:57
  • 1
    Thank you very much. Works perfect. Only manually filter for the second number the results of the first number, so i could -1
    – S.Wiwa
    Oct 7, 2016 at 12:05
-2

You could try:

layer = qgis.utils.iface.activeLayer()? 

I do not know why you still need to use it in the latest QGIS.

1
  • Yes, thats it. Thx. Next problem arise,i modified the question
    – S.Wiwa
    Sep 25, 2016 at 7:45

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.