How to combine 5 columns into 1 filter in Tableau? - tableau-api

My (simplified) data structure is as follows:
I have flagged whether my users have performed a certain action in the last 7 days, 14 days, 1 month, 6 months, and 1 year (1 means the user has performed the action and 0 means he has not). I would like to create a drop-down filter in Tableau where I would be able to filter out the users who have performed the action in the last 7 days, 14 days, 1 month, 6 months, and 1 year. I will have a total number of users at the top of my dashboard and an "action date" filter. Does anyone know how I can achieve this kind of filter in Tableau? I believe I have to create a parameter but I am not sure how to combine these 5 columns into 1 filter.
Any help is appreciated!

The easiest approach to explain is to create a parameter that allows the user to select exactly one value from a prescribed list of strings, such as "7 days", "14 days"... etc. You may also want a few other choices like "Start of Time", or "All users". Whatever options you like.
Then create a (boolean) calculated field that denotes whether the current data record should be included based on the current parameter value. Something like
if [My Filter Param] = "7 Days" then
[7 Days] = 1
elseif [My Filter Param] = "14 Days" then
[14 Days] = 1
...
else // last one
[My Filter Param] = "Start of Time"
end
Then put your calculated field on the filter shelf, choose True as the filter value, apply to whatever worksheets or data sources matter, and of course display your parameter control.
This is a pretty general technique, combine a parameter (for asking the user to make a choice) with a boolean calculated field (to apply the users choice) and the filter or other shelf for applying that calculation to a visualization. Works for all kinds of problems.
If your data sets are large or slow, you can optimize performance in a few ways. Say by using boolean fields in your data instead of integers, and by using integer valued parameters instead of strings so you can use a fast case statement to replace all the string comparisons (although Tableau can optimize some of those comparisons away) If you do use an integer parameter, you can still define the choices to display meaningful strings in the parameter control. See the edit parameter dialog.
Finally, you could consider making your analysis and viz a little more flexible by adjusting your pre-processing to produce data with just two columns -- User and Date_of_Last_Key_Action . Then your users could just use the built-in date filter controls in Tableau to view based on any time range, .e.g, the last 13.5 days if they wanted. You wouldn't need a parameter or calculated field in that case.

You can also re-shape your data. Do like the screenshot GIF

Related

Find count of active users in the last 29 days in Tableau

Require assistance in calculating the Total Active Users from March 16 2020 to Feb 16 2020.
I have tried using calculated fields, but not getting the correct results. Please advise.
Thank you,
Nirmal
To find the number of unique values that appear in a field, say [user_code], you can use the COUNT DISTINCT function, COUNTD() as in COUNTD([user_code])
To restrict the data to a particular time range, one way is put your date field on the Filter shelf and choose the settings that include only the data rows you want — say the range from 2/16 to 3/16 as you stated.
Alternatively, you can push the filtering condition into the calculation with an IF function call, as in COUNTD(IF <data is relevant> THEN [user_code] END) Thus effectively combining the two techniques. That works because if there is no ELSE clause and the IF condition is False then the IF statement evaluates to null. Since COUNTD() silently ignores nulls, like other aggregation functions, the expression acts as if the irrelevant data rows were filtered.
So, for example,
COUNTD(IF [dates] >= #2/16/2020# AND [dates] <= #3/16/2020# THEN [user_code] END)
Will tell you then number of unique user codes during the period between 2/16 and 3/16. The DateDiff() function will probably be useful in more elaborate tests.
Finally, what if you want more flexibility? You could easily use Parameters or Filter controls to let the user choose the date range interactively.
If you want this calculation repeated for each possible day, showing the unique users in the preceding 30 day period, as some sort of rolling calculation, then you’ll need to learn about some more advanced features. Either multiple calculations as above for different time ranges, using Table Calculations, or some data prep and/or data padding with Tableau Prep Builder, Python or some other technique — mostly because in that scenario each data row contributes to multiple rolling counts, rather than one count when partitioning the data by some dimension.

Getting a percentage in Tableau from a yes/no column

I have a spreadsheet of support case management data. I am working with this in Tableau. Each line in the spreadsheet is an individual case. Each case has, among much else, a support agent name and a Yes or No of whether the case work was started within 12 hours. I'd like to know, for each agent, what percentage of the time they started the case work within 12 hours. So, if Bob has 2 "No" and 8 "Yes", he should have 8 / (2 + 8) = 80%.
My attempt at this was to create 2 sets. One is the set of "Yes, started within 12 hours" (those that have "yes" in that field, and one that is the set of "No, not started within 12 hours", the complement to the other set. Silly me, I thought I could do something like COUNT(yeses) / COUNT(nos). Nope, big red failure. So what is the right way to do this?
It would help immensely to please respond as if this is the first thing I have ever done in Tableau. It is. I have learned a lot in this project, but only in comparison to the nothing I knew previously. Please also let me know if I've left out something necessary to answer this. I've tried to be complete but, well, am noob...
If it clarifies anything, here's a poor Excel mockup of data and the effect I'm looking for:
Yes, this is possible and easy in Tableau, but first a couple of points.
The reason your attempt to use COUNT() did not work is that COUNT() does not operate the way you, and that 99% of the people on the planet, expect. COUNT([some expression]) returns the number of records that have a non-null value, any value, for [some expression]. The name comes from SQL relational databases.
The calculations would be just a bit simpler if your third column took the boolean values True or False instead of the string values “Yes” or “No”. (In which case you could drop ‘= “Yes”’ from the formula below)
So two ways to do your calculation are:
Directly with an aggregate calculation which can get the right result, but is hard coded for this case, such as:
SUM(INT([Started within 24 hrs?] = “Yes”)) / SUM([Number of Records])
Using a table calc - which in this case is a bit easier and more flexible.
First, Build a table or viz in Tableau showing SUM([Number of Records]) with the dimensions you care about in play. Say with [Name] on Rows, [Started within 24 hrs?] on Columns and SUM([Number of Records] on Text. Second, Right click on your measure SUM([Number of Records]) and choose Percentage of Total from the Quick Table Calc menu. Finally, use that same menu to adjust Compute Using to specify how you want the percentages computed - in this case, using [Started within 24 hrs?]
If you only want to show some of the data, right click on the column header for the values you wish to hide and choose Hide.
The type conversion function INT() converts True to 1 and False to 0.
You could create another column that converts the Yes's into 1's, and the No's into 0's. Sum up all the 1's and divide it by the total and that's your percentage.
edit: the new column would look something like
=IF(C3="Yes",1,0)
in other words, if Cⁿ is "Yes", then 1, else 0

Tableau Mixed Data

I've been tasked to set up a Tableau worksheet of counts of data (ultimately to create percentages) where the contrived incoming data looks like the following.
id fruit
1 apple
1 orange
1 lemon
2 apple
2 orange
3 apple
3 orange
4 lemon
4 orange
The worksheet needs to look something like the following:
Count of ids
2 Lemons
2 No lemons
I've only been using Tableau for about 4 hours, so is this doable? Can anyone point me in the right direction?
The data is coming in from a SQL Server database in a format that I can control if that helps contribute towards a solution.
Alex's solution based on sets are very good for this scenario, but I would like to show that LODs can be more flexible if you need to extend your solution to include more categories.
for the current scenario, create a calculation with below formula and create text table using COUNTD(Id)
{FIXED [Id]:IF MAX([Fruit]='lemon') THEN 'Lemon' ELSE 'No Lemon' END}
Now for the extension part, you are considering below list where you want to count IDs with Lemon, Apple and others. Since no double counting of Ids are allowed, categorization will follow the order. (This kind of precedence will be a headache without LODs)
Now you can change your calculation as below:
{FIXED [Id]:IF MAX([Fruit]='lemon') THEN 'Lemon'
ELSEIF MAX([Fruit]='apple') THEN 'Apple'
ELSE 'No Lemon or Apple' END}
Now your visualization automatically changes to include the new category. This can be extended for any number of fruits.
This is a good use for a set.
In the data pane on the left sidebar, right click on the Id field and create a set named "Ids that contain at least one lemon" (or use a shorter less precise name)
In the set definition dialog panel, define the set by choosing "Use all" from the General tab, and then on the Condition tab, define the condition by the formula max([Fruit]="lemon")
There are many ways to think of a set, but the most abstract is just as a mathematical set of Ids that satisfy the condition. Remember each Id has many data rows, so the condition is a function of many data rows and uses the aggregation function MAX(). For booleans, True is treated as greater than False, so MAX() will return True if at least one of the data rows satifies the condition. By contrast, MIN() is True only if ALL (non-null) data rows satisfy the condition.
Once you have a set that separates your ids into Lemon scented Ids and others, then you can use that set in many ways - in calculated fields, in filters, in combination with other sets to make new sets, and of course on shelves to make visualizations.
To get a result like your question seeks, you could put your new set on the Row shelf, and put CNTD(ID) on the text shelf or columns shelf. Make sure you understand why you need count distinct (CNTD) instead of SUM([Number of Records]) here.
BTW, the LOD calculation { fixed [Id] : max([Fruit]="lemon") } is effectively the same solution.

Tableau Aggregation of Groups over Fixed Level of Detail

For some reason when I try to group a field created by a fixed level of detail groups containing more then one item disappear from the view.
The basic set up is that there are 'unique event IDs' which are RCIPID which have one or two dates associated with them (some events have two separate dates that are non-linear). There is a 'follow up' date which is tied only to the event location and not the RCIPID, but each RCIPID has only one location.
I've joined the 'follow up' data to the main file based on the location. The below computations [NTC Submission Date] is the date of the event. [Live Date] is the date of the followup. The computations correctly give the number of days after the event that the follow up happened.
However when I try to do a unique count of NTC Date (Or RCIPID) and then group the computations any group with more then one day disappears.
FP - Straight Diff
DATEDIFF('day', [NTC Submission Date], [Livedate])
FP - Remove Negatives
IF [FP - Straight Diff]<0
Then DateDiff('day',[NTC Submission Date],TODAY())
ELSE
[FP - Straight Diff]
END
FP - Days after NTC
{FIXED [Rcip Id], [NTC Submission Date]: MIN([FP - Remove Negatives])}
It works when it is not grouped together
But as soon as I group it all of the groups with more then one day disappear.
Any and all help is greatly appreciated. I think it has /something/ to do with being a dimension, but I honestly don't know what.
The goal is a bar chart similar to the second one, but with the groups "4-5 Days", "6-10 Days", "11-20 Days", and "Over 20 Days" visible. Those values do exist in the data and if I change the view to show the day instead of a count it shows the proper calculations:
EDIT: Using a calculated field instead of groups did not work. Trying a concatenated RCIPID and NTC Submission Date also did not have an effect.
I'm not a huge fan of the group by feature in Tableau as it has give me some unexpected behavior in the past.
There are a few approaches I would recommend trying. One is spelled out well here by using the bin functionality built into tableau. https://community.tableau.com/thread/188952
It sounds like you have some irregular bin sizes you're looking for, in which case you could create a separate calculated field with a series if else statements based on the range of [FP - Days after NTC] and assign a string to each 'grouping'
Lastly, I've not done an LOD of this style with two dimensions "FP - Days after NTC". You only appear to have COUNTD(submission days) on the view shelf. I would verify that you are getting the results you are expecting. And if not, you could create a separate calculated field that is a concatenation of [Rcip Id] and [NTC Submission Date] on which to based your LOD calculation, and then you can use COUNTD on that new field.
EDIT: It was suggested to try using a computed field instead of a group and/or concatenate RCIPID and NTC Date. I tried both and neither affected the result.

Default range for date range filter in tableau

I want to set the default range on a date filter to show me the last 10 days - so basically looking at the lastDate (max date) in the data and default filtering only on the last 10 days (maxDate - 10)
How it looks now:
I still would want to the see the entire range bar on the dashboard and give the user the ability to modify the selected range if he wants to. The maxDate changes after every data refresh so it has to be some sort of a condition that is applied to the filter.
How I want it to look (by default after every refresh of data - new dates coming in):
Any suggestions on how this can be done? I know I can use the relative date and show the data for last 10 days but that would modify the filter and create a drop down which I don't want.
Any suggestions are welcome!
One simple approach that does most of what you want is the following:
Create an integer valued parameter with a range from 1 to some max
you choose, say 100. Call it say num_days.
Show the parameter control on your dashboard as a slider, and give
it a nice title like "Number of days to display"
Create a boolean calculated field called Within_Day_Range defined as:
datediff('minute', [My_Date_Field], now()) < [num_days] * 24 * 60
Put Within_Day_Range on the filter shelf and select the value true.
This lets the user easily select how many days in the past to include, and works to the granularity of minutes (i.e. the last two days really means the last 48 hours, not starting at midnight yesterday). Adjust the calculated field if you want different behavior.
The main drawback of this approach as described so far is that it doesn't display the earliest date possible in the database because that is filtered out. Quick filters do an initial query to get the bounds, which has a performance cost -- so using the approach described here can avoid that query and thus load faster.
If you really need that information on your dashboard, you could create a different worksheet to get just the min([My_Date_Field]) and display that near your parameter control.