What is ATTR (...) aka Attribute function in Tableau?
A video to walk you through how the Attribute function works in Tableau.
- ATTR is an aggregate function that returns a single value if all rows in a group share one value, otherwise it displays an asterisk (null values are ignored)
- Use ATTR to signal hidden detail beneath a mark, surface dimension values in tooltips, and resolve 'cannot mix aggregate and non-aggregate' errors in calculations
- Setting a dimension pill to Attribute (via its drop-down) stops it from affecting the visualisation's level of detail while keeping it available in the marks pane
- ATTR strips out dynamic sorting, can break grand totals, and is slower than MIN/MAX, which often achieve the same result more efficiently
- Aggregation issues in calculations frequently point to a data prep problem better solved earlier in the stack, or with LOD expressions
- What the attribute function is0:28
- Demonstrating ATTR on city and state1:57
- Use case: signalling hidden detail and tooltips4:59
- Use case: fixing aggregation errors in calculations6:42
- Use case: controlling level of detail in the marks pane10:18
- Limitation: loss of dynamic sorting13:10
- Limitation: grand totals not rendering15:04
- Limitation: performance versus MIN/MAX17:54
0:00Hey it's Tim here, in today's video we're
0:01talking about the attribute function inside
0:04of Tableau.
0:04In one of my previous videos where I was
0:06talking about new models in Tableau 2020.4,
0:09I used the attribute function to get me out
0:11of a tight spot inside of a calculation.
0:13And so a subscriber simply asked, "hey can
0:15you go into more detail about that function
0:17?" So here we
0:18are. In today's video what I'm going to do
0:20is tell you what the attribute function is,
0:22some use cases
0:24for it, and then lastly some limitations to
0:26be aware of. Okay let's get stuck in. Okay
0:28to get this
0:28video started it's really important you pay
0:30attention to this next step. I need you to
0:32connect
0:32to the American Superstore sales data set.
0:35That's the second one here on the bottom
0:37left. Okay
0:38as long as you connect into the American
0:39one this is going to work because
0:41essentially I need the
0:42fact that there are cities in the United
0:44States that the name exists in multiple
0:46states. You'll
0:47see what I mean by that in a little bit.
0:50Okay so when we're working with Tableau and
0:53you want to
0:53know what an attribute function is or you
0:55want to know what any function is, you can
0:57actually just
0:58look inside of the product itself to find
0:59out the meaning. I'm going to go ahead and
1:01open the
1:02calculation window here, create a
1:03calculated field and you'll notice that
1:06mine opens up with this
1:07side pane enabled already. Now if you can't
1:09see this don't worry there's this tiny
1:11little arrow
1:11here. This is always frustrating for new
1:13users because when they start out with
1:15Tableau it opens
1:16this window and you don't necessarily know
1:18that there's more to offer when you click
1:20this button.
1:20But when you click this button essentially
1:22you get this list and these are all the
1:24functions that are
1:24available in Tableau. Now at the very top
1:26they're actually grouped okay so you can
1:29see all the
1:29different groupings for these functions. If
1:32I go down to this aggregate grouping you
1:34can see that
1:35the attribute one is right at the top so
1:37that's the first clue. The attribute
1:39function is a type
1:40of aggregation inside of Tableau. What does
1:42it do? Well there's a description right
1:44here so returns
1:45a value of the given expression if it only
1:48has a single value for all the rows in the
1:50group.
1:51Otherwise it displays an asterisk. Null
1:53values are ignored okay so that's
1:55essentially what it does.
1:56Let's take a look at that and I'm just
1:58going to put this here to the bottom so we
2:00can sort of keep
2:00it in view whilst we work with it. We're
2:03also going to work in the data viz pane
2:04whilst that's open. So
2:06I'm going to go ahead and go to location. I
2:08'm going to open up the hierarchy by
2:09clicking this
2:10down arrow here. Then I'm going to drag
2:13city onto rows then state onto rows as well
2:16and what we'll
2:17get is this table. It's a very simple table
2:20that has city on the left state on the
2:22right. Now you
2:23will notice that there are some cities here
2:25that have multiple states. This makes sense
2:28because
2:28Arlington is both the name of a city in
2:30Texas and in Virginia and so on and so
2:33forth. So you get the
2:34idea and Obern exists in three states as a
2:37name. So now we've got this set up
2:40correctly we can
2:41actually start to see what the attribute
2:43function does. What I'm actually going to
2:45do is I'm going
2:45to bring this calculation window back into
2:47context now. I'm just going to call this
2:50attr state. Okay
2:52and what we're going to do is wrap the
2:54state inside of the attribute function. So
2:57let's go
2:58ahead and just write state when we do that
2:59tableau auto complete. So when I just click
3:02that
3:02and then what I'm going to do is I'm
3:03actually going to highlight this is another
3:05hack you can do
3:06when you highlight a field then you double
3:08click the function. Tableau automatically
3:10puts the
3:10function around the thing you've
3:11highlighted. So that's a quick way of
3:13adding attribute to the
3:14whole entire state. Click apply and now we
3:16've got that attribute function here on the
3:18bottom left.
3:19I'm going to go ahead and drag that next to
3:21the state and you'll see essentially
3:25nothing happens.
3:25And this is fundamentally because of the
3:28level of detail that we're working with
3:30inside of this view. Because we are at the
3:33state level of detail the attribute
3:35function is working
3:36correctly. If I just go back to the
3:39description and we just click on this text
3:41here. When you
3:42click on these sometimes they're a little
3:44bit buggy but when you click on the name
3:45here in
3:46the calculation window this always works.
3:48Now returns the value of the given
3:49expression if it
3:50only has a single value for all the rows in
3:53the group. So it's working in this sense
3:55because
3:56everything only has a single value because
3:58the level of detail we're working at is
3:59state. So
4:00there's a one-to-one match for nearly
4:02everything for everything in this table in
4:03fact. Okay now
4:05the thing it will do if there's multiple
4:07values is return an asterisk. So the way we
4:09do that the way
4:10we create this scenario in our view is to
4:12just remove state. So I'm going to go ahead
4:14and remove
4:14state and leave the attribute only. Okay
4:17and you'll notice that now we get the aster
4:20isk that
4:20it was talking about earlier on. The other
4:23thing to note is that it's calling our
4:25calculation and
4:26aggregate. This agg notation lets you know
4:29that this is an aggregate. Okay so we've
4:31somehow managed
4:32to create an aggregate function around
4:34state names essentially. So it's somehow
4:37sort of creating an
4:38aggregation around these things and
4:39essentially returning just one value if it
4:41's the only value
4:42and an asterisk if there's multiple values
4:45and that's essentially what the attribute
4:47function
4:47does. It's pretty much it in a nutshell. If
4:50this is all you take away from the video
4:52then that's
4:52all you need to know. Of course there's a
4:54little bit more to this so we're going to
4:56try and dive
4:56into that in more detail. Let's try and do
4:58that. Okay so we now know what the
5:00attribute function
5:01does. Let's talk about when you might use
5:04this. Okay now if I just bring out a bar
5:06chart here
5:07let's bring cells onto columns to build out
5:10a bar chart and what you'll see here is
5:12that you get
5:12some nice bars here. If I just sort this by
5:16biggest to least you'll see that if I just
5:19undo
5:19that step actually if I just hover over
5:22this particular city Jacksonville you'll
5:25see that
5:25the attribute state has a star and if I go
5:28to the one above it California is in that
5:31place. Now
5:33what is quite common is when you're doing
5:35things like blending inside of Tableau you
5:38will often get
5:38a scenario where multiple items match to
5:41one value and in the visualization that you
5:43're asking Tableau
5:44to create it is not actually possible for
5:47it to aggregate that particular value down
5:50any more or
5:50any less and so it will just return a star
5:53in its place. Okay so in this case if I was
5:55to take
5:56attribute state away from here and put it
5:58on the tooltip you'll see that when I hover
6:01over
6:02what's this Columbus I get a star if I go
6:05to Detroit I get Michigan. Okay so this is
6:07actually
6:08a typical use case for the attribute
6:09function it's essentially telling you hey
6:11there's more detail
6:13underneath this data set. Now back in the
6:15old day you couldn't really solve this
6:17problem easily
6:18because it was really difficult to sort of
6:20create a way for people to drill in you
6:22probably have to
6:22have another chart somewhere else now we
6:25have charts and tooltips and you can just
6:27create a
6:27chart that shows okay yeah this particular
6:30one city exists in these three different
6:32states and
6:32so you can break that view down a little
6:35bit more but in the olden days you couldn't
6:37do that so this
6:38was actually a nice way of letting the user
6:40know there's more detail here they need to
6:41dig into so
6:42that's one use case for that. Now for the
6:44next use case this is the one that actually
6:46came up in the
6:472020.4 video where sometimes when you're
6:49working inside of a calculation you come up
6:51against this
6:52aggregation error okay I'm going to sort of
6:54forcibly create a similar scenario just by
6:56opening up the calculation window and we're
6:58basically going to create like a pretty
7:00pointless
7:00calculation but it should we should try and
7:03make it sort of valid if that makes sense.
7:05So I'm just
7:05going to call this sales in city okay and
7:09what I'm going to say if the city is null
7:12yeah so if is null
7:14city let's just type this in
7:18then null
7:24else sum of sales okay and and man I have
7:32written this in some sort of camel case I
7:34don't know
7:35anything about here so let's just use the
7:37suggestions that it's uh it's sort of
7:40giving
7:40us here I accidentally clicked else if in
7:42that case let's just type in else and you
7:44'll see if I
7:45just sort of um if I just sort of make this
7:47larger you'll see that I'm getting an error
7:51here okay and
7:51if I go down to the bottom here it says
7:53cannot mix aggregate and non-aggregate
7:56comparisons or results
7:57in if expressions okay so what's going on
8:00here okay let me sort of say this in plain
8:03English
8:03it's basically saying that over here I'm
8:05doing some aggregation I'm summing
8:07everything up
8:08and yet over here I'm basically just
8:11checking a single city so it's basically
8:13saying hey you
8:14can't simultaneously ask me to add
8:16everything up but then the beginning of the
8:18calculation asks me
8:20to compare with something that isn't added
8:22up okay so it wants me to aggregate the
8:24city in this
8:24particular case now the way I do that is
8:27coincidentally with the aggregate function
8:30okay
8:31and the reason it makes sense here is
8:32because when we then bring it into the view
8:34as long as
8:35we've got city on rows this calculation is
8:37still going to make sense so let's go ahead
8:40type in
8:40attr so this is the trick I used last time
8:43essentially just helped me clear out this
8:45error
8:46that I was getting and now you see the
8:48calculation is valid so if you're trying to
8:50write a calculation
8:51and you're getting into some aggregation
8:53issues and the thing you're trying to
8:55aggregate doesn't
8:56make sense to aggregate like a name or
8:57dimension or something like that that doesn
9:00't make sense
9:00because it's it's a sort of a grouping or
9:03an attribute of a dimension then this is
9:05what you
9:06do you essentially use the attribute
9:08function to sort of try and get past that
9:10error and now you
9:11can see the calculation is valid if I just
9:13go ahead and use that in my field I just
9:15say apply
9:16cells and city drag that next to that and
9:19you'll see it's exactly the same chart
9:21there is no issue
9:22here but if I was to remove the attribute
9:24item there then it would cause us an issue
9:27so that's
9:28pretty much the other use case so there's
9:30three use cases really like I showed you
9:32telling you
9:32there's multiple items inside of a
9:34particular grouping or particular level of
9:37detail the second
9:38is getting information into tooltips so
9:40when someone hovers over a bar chart or
9:43something
9:43like that where there is more detail in
9:45there then they can see that I'll just
9:48close this and I'll
9:49show you again this is still sort of the
9:51case here when I hover over Springfield
9:53here I get a star
9:54when I go to Jacksonville I get a star when
9:57I go to San Diego I only get California
9:58because that's
9:59the only item there and then the other way
10:02of doing this is of course in a calculation
10:05window
10:05where you have a little bit of a challenge
10:08so if I go in here cells and city you're
10:11trying to do
10:12an aggregation it's not letting you this is
10:14what's going on okay now we're not done yet
10:17because
10:18there's still more places you can see
10:19something called attribute okay what we
10:21have here is a very
10:22simple view and I'm going to actually work
10:23from here onwards I'm going to remove cells
10:25and city
10:26from the top row so we just got cells and
10:29city in context now the next thing I want
10:33to do is add
10:34something into this view and the thing I
10:36want to add is going to be at a higher
10:38level of detail
10:39than city okay so I'm going to add the
10:42country field let's go ahead here sorry it
10:46's a little
10:46bit further up this hierarchy I'm going to
10:49add country onto detail now when I do that
10:51it doesn't
10:52change anything meaningful in the
10:53visualization which is a good thing okay
10:56but watch what happens
10:57as I start to expand these items let's just
11:00add a region and now you'll notice that
11:02Springfield
11:03because it exists in multiple states can
11:06also exist in multiple regions okay so you
11:09can see
11:09here that this region is sort of west this
11:13is south this is east and this is central
11:17okay
11:18and so what's actually happening here is
11:20this our region field is controlling the
11:22level of detail in
11:23our visualization I know that because it's
11:25got this little icon here which is the same
11:28as this
11:28one here in the marks pane which is
11:30basically telling you that hey this item is
11:32actually
11:33affecting the lowest level of granularity
11:35in the visualization how do I get around
11:37that well this
11:38is how if I want to keep region in the view
11:40so that it can be used in a tool tip but I
11:42don't
11:43want it to affect the visualization what I
11:45can do is I can essentially turn this into
11:47an attribute
11:48so if I go in here click this drop down you
11:50'll see that one of the items here just
11:53after dimension is
11:54attribute and when I do that notice that it
11:57no longer affects my visualization so this
12:00is yet
12:00another use case for this particular
12:03capability it's going to do exactly the
12:05same thing so if I
12:06go back to Springfield you'll see that I
12:09now get a star for my regions okay
12:10essentially what this
12:12has done is it stopped region from
12:14controlling the way my visualization works
12:16it stopped it from
12:17sort of messing up the level of detail and
12:19actually that's a very deliberate trick
12:21that you can use if
12:22you just want to bring something into the
12:24view but you don't want it to interfere
12:25with your chart
12:26especially if it's the dimension you can
12:28just bring it in you can do this with
12:30virtually
12:30anything so if I go ahead here and get the
12:32product name if I put this on detail you
12:35notice it
12:35completely messes up my chart turn it into
12:38an attribute and boom my chart goes back to
12:40normal
12:41but now the product information is in the
12:44view the problem is here is that there's
12:46just so many
12:47products I'm always going to see a star
12:49here so it's really sort of pointless but
12:51if I need the
12:52product name in there this is going to work
12:55now if you're really advanced with Tableau
12:57and you'll get
12:58into use cases where having this
13:00information in the marks pane is necessary
13:02in order to achieve
13:03something else but that's for another video
13:04and that's for another day so that's pretty
13:06much the
13:07last use case you'll see for this okay
13:09limitations this is all we've got left to
13:11cover now there are
13:12some limitations with using the attribute
13:15function I've just reset the view here so
13:17we're back to a
13:18plain old data source I've cleared
13:19everything from the sheet and we've pretty
13:22much reset the work
13:22because if we've started from a fresh now
13:25one of the things I want to show you is to
13:26do with
13:27dynamic sorting what I'm going to do is I'm
13:30going to drag sales onto text then I'm
13:32going to drag
13:33subcategory onto rows this gives us a list
13:36of subcategories and essentially the values
13:38that go
13:39with them now I'm also going to create a
13:41calculated field I'll right click on the
13:43field create
13:43calculated field and what I'll do for this
13:46one is I will just set this to an attribute
13:50as we did
13:51before so I'll just wrap this in the
13:53attribute this time I'll type it out just
13:55just to show that
13:56I'm a lazy person and I'll call this ATTR
13:58sub cat okay so now we're pretty much ready
14:01to go that's
14:02all good hit apply perfect it's now gone
14:04over here to the bottom left hand side now
14:07if I drag that
14:09next to the subcategory you'll see that
14:11basically it says the same thing but when
14:13it comes to sorting
14:14it's a slightly different story if I go to
14:16the first one here and I click sort you'll
14:18see that
14:19I have the full capability of sorting I can
14:22do all the sorting I want including any
14:24dynamic sorting
14:26based on a field so you can see that the
14:28sort changes depending on what I'm actually
14:30counting
14:31here the minimum the maximum each time this
14:33is changing this is called dynamic sorting
14:36however if I then go to my second one let
14:38me just clear the sort when I go over here
14:42and I go to
14:42sort you'll see that I can only really sort
14:45it by the manual formats there's no dynamic
14:48sorting
14:49available to me here because I'm using an
14:51attribute function around the dimension so
14:53just a word of caution you lose this
14:55ability when you're using an attribute
14:57function so just be
14:58aware of that if you need to sort with an
15:00attribute you lose a lot of capability okay
15:02the next one is
15:03slightly easier to show you okay let's just
15:06open up a new sheet and what I want to do
15:08here is I
15:09want to create a grand total so what I'm
15:11going to do is I'm going to drag sales put
15:13it onto text again
15:14order date onto rows actually I want to put
15:17this on columns not rows and then I want to
15:19bring the
15:19subcategory here again okay and here we
15:22have a list of values now the use case here
15:25is that if
15:26you've used an attribute inside of a
15:28calculation what could happen sometimes is
15:30that the grand
15:31total won't render correctly okay let me
15:33show you like a forced example it's not
15:36quite the same as
15:37sort of a standard example you'd bump along
15:39because you would never write a calculation
15:41like this but
15:42I've just got to try and sort of recreate
15:43the scenario here so let's just close the
15:46side window
15:46because I now know what the attribute
15:48function is and I'm just going to sort of
15:50forcibly type
15:50something so I'm going to say if attribute
15:56not the subcategory if attribute actually
16:02yeah we can
16:02actually reuse that if attribute sub
16:04category let's use that let's use the same
16:06field we've just
16:07brought in I was going to do something else
16:09but we've already created a function that
16:11does that
16:11equals and let's say we're checking for
16:14something here a simple string let's say
16:18art
16:20then some of cells okay and I forgot my
16:24brackets so nothing
16:26automatically formatted let's just close
16:29that off and capital s for cells and now it
16:33gets going man
16:34I cannot spell here we go then some cells
16:36uh end okay we don't need to do an else
16:38because there's
16:39nothing else coming after that it just
16:40assumes that it's null if there's nothing
16:42after that okay
16:43so if attribute equals r then some of cells
16:45end okay so we'll call this attribute cells
16:48just to
16:49show that it's only going to show uh if the
16:51art attribute is basically the item so I'm
16:54going to
16:54hit apply hit okay and what we're going to
16:57do is we're going to remove this cells
16:59value from the
17:00view and we are going to put this on text
17:03instead so so far so good it's doing
17:06exactly as we
17:07expected we're getting the individual
17:09values for art and for nothing else however
17:12if I then go and
17:14enable a grand total a column grand total
17:16in this case you'll see the total doesn't
17:19work correctly
17:20and so this is another use case for
17:22attribute or limitation is that grand total
17:25sometimes won't
17:26render correctly now the fix for this is to
17:28use a min or max but then again might not
17:30render the
17:31right values so just be very careful about
17:33how you sort of solve this this really
17:35typically points to
17:37where the data prep issue you probably want
17:39to solve this problem further back in the
17:41stack as
17:41it were as the data comes in maybe doing
17:43something like order of operations to get
17:45around this problem
17:46LODs exist now as well so you can actually
17:48do this sort of more dynamically using that
17:51anyway
17:52but just something to be aware of and then
17:54the last thing is to do with performance I
17:56'm just
17:56going to build a very simple list actually
17:59maybe what I'll do is I will take a
18:01category
18:02and subcategory and put that next to each
18:05other okay so we've got a bunch of subc
18:08ategories that
18:09are part of categories now when we use the
18:11attribute function in this particular use
18:14case
18:14I'm not actually going to write anything I
18:15'm just going to stay on the screen what the
18:17attribute
18:18function has to do when it looks at each
18:20grouping here by grouping I'm talking about
18:22the categories
18:23is that for each category it has to go and
18:25look at what's inside of the subcategory so
18:29it will
18:29start with bookcases and then realize that
18:31bookcases and tables are not the same thing
18:33and so by doing that what that means is it
18:36has to load the entire data set in there
18:38okay now
18:39one of the things is that Tableau is
18:40actually very efficient and it sort of when
18:42you use something
18:43like an extract it pre-indexes the data and
18:45it understands a little bit about what's
18:47going on
18:48and so if you just need the smallest or the
18:51largest value in a particular table it's
18:54actually not a
18:55good idea to use attribute if the result
18:57would be achieved the same way if you used
19:00min or max
19:01okay because min or max will be much faster
19:03at finding what's first and last than
19:05something like
19:06an attribute so it's something to be aware
19:08of sometimes you're using attribute to
19:10solve a
19:10problem in the visualization when in fact
19:12you don't actually even need the capability
19:14that
19:15attribute is offering you it's just getting
19:17past the viz like I showed you earlier so
19:19in those
19:19cases you might be better off using using
19:21something like min and max to get around
19:23the problem rather
19:24than using something like attribute so it's
19:27a bit of a weird one to sort of show you
19:28and I need to
19:29think sort of more creatively in terms of
19:31examples maybe if you've got an example
19:33post it in the
19:34comments below and other people can benefit
19:36from that but that's pretty much it for
19:37limitations
19:38those are the three kind of key ones those
19:40are the ones that tabla also document on
19:41their help pages
19:42and that are worth highlighting so that's
19:44pretty much it that is the attribute
19:46function in a
19:46nutshell and there's definitely more we
19:48could have dived into but fundamentally
19:50this is all you
19:50really need to understand in order to use
19:53this day to day the first one is just using
19:56it to tell you
19:56if there's more detail underneath the thing
19:59you're analyzing it will show you a star if
20:01there is and
20:02it won't if there isn't it will show you
20:04the lowest level item in that particular
20:06group the other use
20:07cases inside of a calculation and the final
20:09use case is in this view where you need to
20:12change the
20:12level of detail without removing
20:14information from the marks pane the rows
20:16columns or anything else
20:18okay that's pretty much it in a nutshell if
20:19you've enjoyed this you know what to do if
20:21you haven't
20:22let me know in the comments below and I'll
20:23catch you in the next video
The Attribute function is commonly used but not often well understood. It’s also used to help clear aggregation errors in Tableau but it’s quite easy to use it without understanding why. In this video, I explain some use cases, some limitations and how to use it.
Tableau release Notes / KB on the function with sample workbook >>.