QGIS Field Calculator – Performing Cumulative Sum with Non-Numerical Index in QGIS Field Calculator

accumulatedattribute-tableexpressionfield-calculatorqgis

I need to create an attribute with cumulative sum of another attribute. The values are sorted by a string attribute. I just found posts that involved the numerical id of the features.

I've tried to make a expression with the previous feature name but it only works for the first three features in the table, all after that remain NULL.

That's the expression:

if (name = 'P00-P01', attribute('dist'), attribute('dist') + attribute(get_feature('route', 'name', if (to_int(substr(name, 2,2))-1<10, concat( 'P0', to_string(to_int(substr(name, 2,2))-1),'-',substr(name ,0,3 )), concat( 'P', to_string(to_int(substr(name, 2,2))-1),'-',substr(name ,0,3 )))),'cum_dist'))

Table with only three cumulative values

Using the index in the expression the result remains the same.

if (name = 'P00-P01', attribute($currentfeature, 'dist'), attribute($currentfeature, 'dist') + attribute(get_feature_by_id('route', $id-1), 'cum_dist'))

I've tried also the aggregated() function but every time the QGIS crashes.

Someone have a guess about this bug?

Best Answer

Solution using PyQgis (python)

I could not figure out how to solve this using expressions (but saw a solution after posting, see below), so I'll suggest you to use python for the solution. The following code should do the job:

# lines beginning with """ are comments to describe a block of code
# lines and text starting with # are comments too

layer = QgsProject.instance().mapLayersByName('route') # returns a list of all layers called "route" in your interface
layer = layer[0] # returns the first layer of the list

"""add a new field called 'cum_dist'"""
pr = layer.dataProvider() # set the data provider
pr.addAttributes([QgsField('cum_dist', QVariant.Double)]) # adds a field to your layer
layer.updateFields() # update the layer fields

"""add values to the new cum_dist field"""
cum_dist = 0 # initialize the distance at 0
for feature in layer.getFeatures(): # loop over all features with a for loop
    geom = feature.geometry() # get the geometry of the feature
    length = geom.length() # get the length of the geometry
    cum_dist = cum_dist + length # update the cumulative distance
    
    with edit(layer): # this sets the layer in edit mode for this code block
        feature['cum_dist'] = cum_dist # set the value of the field 'cum_dist' to the value of the variable cum_dist
        layer.updateFeature(feature) # update the feature values

Sources:
https://anitagraser.com/pyqgis-101-introduction-to-qgis-python-programming-for-non-programmers/pyqgis101-creating-editing-a-new-vector-layer/
https://gis.stackexchange.com/a/168872/200573

Solution using expression

with_variable (
    'fid',
    fid,
    sum( $length, filter:=fid<=@fid)
)

Source: Cumulative SUM in QGIS attribute table

Related Question