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.

mgri
16.4k6 gold badges48 silver badges80 bronze badges
asked Sep 23, 2016 at 9:09
2
  • 3
    QGIS version? OS? Personally I would do this in Excel, export to CSV, import in QGIS and then join. Commented 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. Commented 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.

answered Sep 23, 2016 at 13:27
8
  • ok, get the error "name 'iface' is not defined" Commented 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) Commented Sep 23, 2016 at 16:33
  • i'd put the code into the question Commented 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. Commented 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 Commented 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.

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
answered Sep 23, 2016 at 20:07
1
  • Yes, thats it. Thx. Next problem arise,i modified the question Commented Sep 25, 2016 at 7:45

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.