Combine and replace values in a data expression?

762
8
01-14-2022 11:13 AM
natasha
New Contributor II

Hi! I'm working on a dashboard where I need to configure the data. My data contains a field with multiple number values. When decoded, more than one of the numbers represent the same text value:

 

Type

1 = Human

2 = Human

3 = Human

4 = Bird

5 = Bird

6 = Plant

7 = Plant

I'd like to decode the numbers or replace them with the strings they represent.

So I'd like to take my data from this:

RegionType_num
North4
South2
West7
North1
South5
East3
North3

 

to this:

RegionType_text
NorthBird
SouthHuman
WestPlant
NorthHuman
SouthBird
EastHuman
NorthHuman

 

I know I can use a data expression and create a new feature set. But I'm pretty new to data expressions and just not sure how to incorporate this into one and whether or how to use decode, replace, or another function.

 

Eventually, I'd like to get the count and percentage of each Type (using its text name) by region.

 

Thanks so much for your help!! 

0 Kudos
8 Replies
jcarlson
MVP Esteemed Contributor

There is a decode function. What context are you using this in? You could also use Arcade's Dashboard Formatting to simply decode that attribute, if it was for a list or something.

var codes = [
    1,
    2,
    3,
    4,
    5,
    6,
    7
]

var decoded = []

for (var c in codes){
    var d = Decode(
        codes[c],
        1, 'human',
        2, 'human',
        3, 'human',
        4, 'bird',
        5, 'bird',
        6, 'plant',
        7, 'plant',
        ''
    )
    
    Push(decoded, d)
}

return decoded

Returns

[ human , human , human , bird , bird , plant , plant ] 
- Josh Carlson
Kendall County GIS
0 Kudos
natasha
New Contributor II

Thanks! Yeah, I know about the decode function and eventually I want to be able to use a selector, so that the user can select one or more Types to filter a point layer on the map and other dashboard elements. I think for that I'd need a data expression, right? I don't know how to use the decode function within a data expression yet... would you populate need a dictionary?

0 Kudos
jcarlson
MVP Esteemed Contributor

Ah, okay. If you need to use a selector based on the decoded values, then a data expression is the way to go. Yes, you'd need to populate a dictionary. If it's literally just decoding the values, you can try this:

var portal = Portal('your-url')

var fs = FeatureSetByPortalItem(
    portal,
    'itemid',
    0, // or whatever layer index
    ['region', 'type_num'],
    false
)

// create vars to populate feature array
var features = [];
var feat;

for (var f in fs){
    var d = Decode(
        f['type_num'],
        1, 'human',
        2, 'human',
        3, 'human',
        4, 'bird',
        5, 'bird',
        6, 'plant',
        7, 'plant',
        ''
    )

    feat = {
        attributes: {
            region: f['region'],
            type_text: d
        }
    }

    Push(features, feat)
}

var out_dict = {
    fields: [
        {name: 'region', type: 'esriFieldTypeString'},
        {name: 'type_text', type: 'esriFieldTypeString'}
    ],
    geometryType: '',
    features: features
}

return FeatureSet(Text(out_dict))

 

- Josh Carlson
Kendall County GIS
0 Kudos
natasha
New Contributor II

Thanks Josh! That is helpful. Now that I am able to decode and group the categories, and add a selector with the appropriate text categories, I am stuck on how to use configure the selector to trigger an action (filter) on a layer on a map using the layer's target field, since the layer doesn't contain matching values in that field anymore. Any thoughts?

0 Kudos
jcarlson
MVP Esteemed Contributor

Oh, that's right. Okay, amend the original expression's feat and out_dict as follows:

    feat = {
        attributes: {
            region: f['region'],
            type_text: d,
            type_num: f['type_num']
        }
    }

    Push(features, feat)
}

var out_dict = {
    fields: [
        {name: 'region', type: 'esriFieldTypeString'},
        {name: 'type_text', type: 'esriFieldTypeString'},
        {name: 'type_num', type: 'esriFieldTypeInteger'}
    ],
    geometryType: '',
    features: features
}

 Then your selector should be able to act against your layer by matching the type_num field.

- Josh Carlson
Kendall County GIS
0 Kudos
natasha
New Contributor II

Hey Josh, thanks! Now the type_num field should be in the feature set, but since the category selector uses type_text as the category field and that is the default source field for the filter, it still doesn't match the available target field (type_num) and so it doesn't filter the layer. Do you know if there's a workaround? Again, thank you!

0 Kudos
jcarlson
MVP Esteemed Contributor

I've been wracking my brains over this one, and I don't think it will work, actually. Since the selector uses grouped values based on a field, it can only filter based on that grouped field. The only alternative is to use a static filter, but you'd need one option per value, which defeats the purpose of grouping these things in the first place.

I'm thinking the only way to do this would be to create a new field and filter by that.

- Josh Carlson
Kendall County GIS
0 Kudos
natasha
New Contributor II

Hi @jcarlson! I had given this a rest for a while, but over 2 years later, been thinking about this project again, and decided to revisit the problem...

Do you have suggestions on how to use the decode/when function in a data expression so that the decoded values can be used as categories in a dashboard category selector -- (like by adding a field with the decoded values as per your last suggestion) if I don't actually own the data? Thanks!

0 Kudos