1

I want to make a model that gives me the features in a dataset that have the last actual value based om the attributes in the model. The dataset is struktures as there is not always a variable 3 and 4. This makes it give empty results because where is no feedback mechanism that makes it choose an earlier step as a valid result.

Do you have a way to make the model extract the features that fits the variables the most?

An example would be if v1 is 5, v2 is 12, v3 is 4, but v4 is balnk (NULL). The way i have made the model now it needs to have something inn all variables to give a result.

example of setup

1
  • Are the variables Selection attributes or Values in Select by attribute?
    – BERA
    Jan 4 at 14:19

1 Answer 1

2

Instead of repeating four times the Select by attribute and then Extract selected features, you can use a much simplified version with just one algorithm Extract by expression. Create an expression that fulfills the conditions for all four variables at once.

Like "value" in (1,2,3,4) selects all those features where field value is 1, 2, 3 or 4. You can replace the numbers by the variables and have to enclose the expression as a string in an eval() function:

eval ('value in ( @variable1 ,  @variable2 ,  @variable ,@variable4 )')

This works even if one ore more of the variables are NULL.

enter image description here

Input = red points: running the model with two variables empty extracts all the features where value corresponds to one of the variables not NULL (here: 2 or 3). Output: blue points enter image description here


Edit

As you stated in your comment, you want to extract only exact matches. In this case, the solution above works as well, however you must adapt the expression - the rest remains the same.

Use this expression:

eval (
    'array_sum (
        with_variable (
            ''array1'',
            array_foreach (array (@v1,@v2,@v3,@v4), if (@element>0, @element,''null'')),
            with_variable (
                ''array2'',
                array_foreach (array (value1,value2,value3,value4), if (@element>0, @element,''null'')),
                array_foreach (
                    generate_series (0,3),
                    @array1 [@element] = @array2 [@element]
                )
            )
        )
    )=4'
)

You might have to adapt:

  • Line 5: name of the variables (here: v1, v2 etc.)
  • Line 8: name of attribute fields (here: value1, value2 etc.)

Red points, labeled with value1 to value4 (what in the label appears as 0 in fact is NULL); yellow circle is the output-point of the model: only exact matches in the same order (1,3,5,0) are extracted; values 1,3,0,0 and or 1,5,3,0 (red circle) are ignored: enter image description here


I also add a generic solution if you do not have exactly four elements to compare, but a flexible number. Just make sure both number of variables and of fields (lines 4 and 7) are the same length (like: array (@v1,@v2) and array (value1,value2) for two elements):

eval (
    'with_variable (
        ''array1'',
        array_foreach (array (@v1,@v2,@v3,@v4), if (@element>0, @element,''null'')),
        with_variable (
            ''array2'',
            array_foreach (array (value1,value2,value3,value4), if (@element>0, @element,''null'')),
            array_sum (
                array_foreach (
                    generate_series (0,array_length(@array1)),
                    @array1 [@element] = @array2 [@element]
                )
            )= array_length(@array1)
        )
    )'
)
2
  • think i maybe have descibed the problem a bit clumsy. The problem is that if i have a dataset eks. 1,3,5,NULL 1,3,NULL,NULL 2,4,NULL,NULL and i give the inputs v1=1, v2=3, v3=5 v4= I want it to only give me the featture with 1,3,5, NULL
    – Endre Aaen
    Jan 5 at 8:09
  • See Edit for a solution that does that
    – Babel
    Jan 5 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.