Calculate median and average in a partition in Tableau using table calculation - tableau-api

I have a details table of posts and subjects digged from a forum. Row is the single subject (ie postID and subjectIS is the primary key for the table), then I have some measures at subject level and some at post level. For example:
+---------+-------------+--------------+------------+--------------+--------+
| post.ID | post.Author | post.Replies | subject.ID | subject.Rank | year |
+---------+-------------+--------------+------------+--------------+--------+
| 1 | mike | 10 | movie | 4 | 1990 |
| 1 | mike | 10 | comics | 6 | 1990 |
| 2 | sarah | 0 | tv | 10 | 2001 |
| 3 | tom | 4 | tv | 10 | 2003 |
| 3 | tom | 4 | comics | 6 | 2003 |
| 4 | mike | 1 | movie | 4 | 2008 |
+---------+-------------+--------------+------------+--------------+--------+
I want to study the trend of posts and subjects by year and color it by subject.Rank.
Firsts are easily measured putting COUNTD(post.ID) and COUNTD(subject.ID) in rows and 'year' in column.
But if I drag MEDIAN(subject.Rank) in Color, I got a wrong result: it's not calculated at distinct subject.ID level but at row level.
I think I can accomplish it using table calculation features, but I have no idea on how to proceed.

It sounds like you are trying to treat Subject.Rank as a dimension, instead of as a measure. If so, just convert it to a dimension on the worksheet in question by right clicking on the field and choosing dimension. You can also convert it to a dimension in the data pane by dragging the field from the measures section up to the dimensions section. That will tell Tableau to treat that field as a dimension by default in the future.
A field can be treated a dimension in some cases, and a measure in others. Depends on what you are trying to achieve. If you are familiar with SQL, dimensions are used to partition data rows for aggregation using the GROUP BY clause.
Finally, count distinct (COUNTD) can be expensive on large datasets. Often, you can get the same result another way. So try to think of other approaches and save COUNTD for when you really need it.

Try using {fixed [1st LEVEL],[2nd level]: median()}
or
Table calculation approach
when you put in median there is an edit table calculation under advance compute using put you fields in there(Make sure its ordered the way you want it to calculate when you select them) then click OK select the at which level and restart every

Related

Kafka / KSQL, stuck in reducing stream/table

What I have, are two streams (from two different systems, imported via connectors). Some of the information from the different streams will be used to build combined information.
Currently, I'm working with ksqlDB but I'm having problems with the last step to reduce the information from both streams.
Both streams contains a tree structure (id/parentId), so I've used a second table for each stream to find certain information from the parents, which is then joined into a table containing all the information to do the final reduce.
The main matching column is always the same, however, one or more columns (not fixed) is also needed to do the final match. The columns might also be partial matches between them.
An example output of the table might look like this:
| id | match | matchExtra1 | matchExtra2 | matchExtra3 |
| 1 | 1 | Extra1 | Extra2 | Extra3 |
| 2 | 1 | Extra1 | Extra4 | Extra5 |
| 3 | 1 | Extra6 | Extra7 | Extra8 |
| 4 | 1 | Extra9 | Extr10 | tra8 |
In this case, id 1 and 2 should be matched and id 3 and 4 should be another match.
If this is possible within ksqlDB, that would be great. If needed to work with low-level Kafka, that's fine as long as we can achieve the end result.
Basic flow as I have it right now:

Getting breakdown of "Others" (the rest of Top N members) with SSAS MDX

How can I recursively get the breakdown of "Others" when Top N is applied to dimensions?
Imagine a measure Sales Amount is sliced by 3 dimensions, Region, Category and Product, and Top 1 is applied to each dimension. The result I want to see is a table like below. On each slice, the rest of members are grouped as "Others".
Region | Category | Product | Sales
============================================
Europe | Bikes | Mountain Bikes | $100
| |------------------------
| | Others | $ 30
|-----------------------------------
| Others | Gloves | $ 50
| |------------------------
| | Others | $120
--------------------------------------------
Others | Clothes | Jackets | $ 80
| |------------------------
| | Others | $130
|-----------------------------------
| Others | Shoes | $ 90
| |------------------------
| | Others | $110
--------------------------------------------
When an "Others" appears, I want to see the Top 1 of the next dimension within the scope of this "Others". This seems a little tricky. e.g. tuples like (North America, Clothes) and (Central America, Clothes) need to be aggregated as (Other Regions, Clothes). Is there a neat way to aggregate the measure based on the 2nd dimension, Category?
Alternatively, I think a sub cube that filters out Europe will easily provide the breakdown of Other Regions, Clothes and Other Categories. However, this is likely to result in creating many dependent queries. For an easy processing of the result set, it would be ideal if the query returns data in the above format.
Can this be possibly achieved by a single MDX query?
To get the breakdown of others we must use dynamic set, EXCEPT() and aggregate functions
in each of the three dimensions we will need to create a named dynamic set that holds too members (top 1 and others ).
as exemple, in the dimension category i have created a dynamic set that holds two members (Top 1 and others) like this :
CREATE MEMBER
CURRENTCUBE.[Product].[French Product Category Name].[ALL].[OTHERS] AS
AGGREGATE(EXCEPT([Product].[French Product Category Name].[French Product Category Name].MEMBERS,
TOPCOUNT([Product].[French Product Category Name].[French Product Category Name],1,[Measures].[Sales Amount])
));
CREATE DYNAMIC SET [TOP1 and Others]
AS {TOPCOUNT([Product].[French Product Category Name].[French Product Category Name],1,[Measures].[Sales Amount]),[OTHERS]};
because the set is dynamic then the values of top 1 and others will change according to the filters and slicers that you applay.

Optimal relational design for groups and subgroup relationships

I have a bit of an intro-level relational database design question. I'm working on a project where I'm capturing information from scientific journal articles and storing that in a Postgres database. One of my primary goals is to define a schema that is flexible enough to cover most cases I might encounter in a broad set of papers. In reality, articles tend to report a semi-standard set of details, but there's definitely variance once you get into the details. These things are written for humans, not machines.
For the most part, defining the schema has been pretty straightforward, but one thing I'm stuck on is how to sensibly structure a set of tables to capture details about a study's subject groups and subsets of subjects.
Take for example a simple randomized control trial - you typically have a set of people identified as screened for eligibility, a set determined to be eligible, a set randomized into the control group, and a set randomized into the treatment group. Within each of those groups you can have subgroups defined in all sorts of specific ways, but generally by some sort of interval (e.g. Age 26-32) or a category (e.g. pregnant/not pregnant).
Currently, I've set this up so that a Study record can have many Subject records, and Subject records can have many Interval_Subgroup records and many Categorical_Subgroup records.
Subject
-----------------------------------------
id | groupType | measure | value | study
-----------------------------------------
13 | treatment | count | 578 | 17
14 | control | count | 552 | 17
Interval_Subgroup
---------------------------------------------------------------
id | factor | factorMin | factorMax | measure | value | subject
---------------------------------------------------------------
41 | age | 18 | 24 | count | 125 | 13
42 | age | 25 | 32 | count | 204 | 13
Categorical_Subgroup
-----------------------------------------------------
id | factor | factorValue | measure | value | subject
-----------------------------------------------------
74 | sex | male | count | 251 | 13
75 | sex | female | count | 327 | 13
This seems workable, but feels clunky because I have two tables for capturing the same type of information. Also it's limiting because it wouldn't allow me to capture any combination of subgroup sets like males of age 18-24. Some studies report that kind of detail, some don't, but I want to be able to capture any depth of subgroup info the paper offers.
What is a more flexible way to structure these tables than what I've described above? I'm trying to sketch out how I think this should work, and right now, I have subject groups having many subgroups and subgroups having many subgroup definitions. There would just be one table capturing measurements about subgroups, and another table for defining what each subgroup is. I'm not sure if that is in the right direction. Maybe there is a far more simple solution that you might know of.
Thanks for taking the time to help out - it's much appreciated!
Edit:
Fixed id to be unique in the example tables.
From your description it sounds like a factor is a thing, and that each subgroup has one or more factors. To me this implies that factor needs its own table. Factors can in turn be of type interval or categorical, which means single table inheritance might be in order.
Example tables might look something like this:
subgroups
------------------------------
id | measure | value | subject
------------------------------
41 | count | 125 | 13
42 | count | 204 | 13
factors
id | type | factor | category | interval_min | interval_max | subgroup
-----------------------------------------------------------------------------
68 | interval | age | NULL | 18 | 24 | 13
69 | categorical | sex | male | NULL | NULL | 13
In this example subgroup 41 has two factors, age 18-24 and gender male.
It could also be that STI is overkill here, in which case you'd split factor into two tables, categorical_factors and interval_factors, and a subgroup could have zero or many of each.
As far as I'm aware, the complexity of using STI mostly depends on what ORM you're using. Rails / ActiveRecord has good support, other frameworks vary.
Hope that helps!

Calculate the percentage of a column which has redundant rows in Tableau

I want to calculate the percentage of a column which has redundant rows.
For example ... I would like to calculate the percentage of "Success" for A and B in the below table
+-------+---------+
| Name | Result |
+-------+---------+
| A | Success |
| B | Success |
| A | Fail |
| A | Success |
| B | Fail |
| B | Fail |
| A | Success |
+-------+---------+
I tried using Calculated field by putting If([NAME]) = "Success" then 1 else 0
and then editing the table calculation to Percentage -> table across and down... but didn't work :(
You can absolutely use the "Percent of Total" table calculation for this. The tricky bit is going into the "Edit Table Calculation" dialog and telling Tableau how you want it to perform the calculation.
Here's an example of how to do this that you can adjust to fit your specific needs. Place [Name] and [Result] in the Rows shelf. Then place SUM(Number of Records) into Text. You'll end up with something like this:
Name Result | |
---------------------+-----+
A Fail | 1 |
Success | 3 |
--------------------+-----+
B Fail | 2 |
Success | 1 |
--------------------+-----+
Then right click on SUM(Number of Records) and click "Add Table Calculation...". At the top of the Table Calculation dialog, go to "Calculation Type:" and choose "Percent of Total". In "Summarize the values from:", it will default to "Table (Down)". Go ahead and hit Apply at this point and see what happens. Bad news - it's wrong.
Name Result | |
---------------------+-----+
A Fail | 14% |
Success | 43% |
--------------------+-----+
B Fail | 29% |
Success | 14% |
--------------------+-----+
The default "Table (Down)" is almost never what you actually want. That says to calculate the percent of total for your entire partition, but you'd actually like to see that percent of total for each Name.
Until you get really good at this part (and maybe even after you've become a Tableau Zen Master and a Tableau god among men), I recommend always going to the advanced menu when you're defining your table calculations. It's a good opportunity to really think through exactly how you want Tableau to perform the calculation. In this case, you want to calculate the percent of each result (Success and Fail) for each name.
Go to the Advanced dialog (under "Summarize the values from:"). You'll see Name and Result under Partitioning and nothing under Addressing. Move Result over to Addressing and leave Name under Partitioning. What you're saying here is "I want Tableau to calculate the percent of each result (Success or Failure). I want it to do this for each name."
Apply those changes, and you should see something like this:
Name Result | |
---------------------+-----+
A Fail | 25% |
Success | 75% |
--------------------+-----+
B Fail | 67% |
Success | 33% |
--------------------+-----+
Perfect. If you just want to see the Successes, just right click on "Fail" in the table and click Hide. Do NOT filter them out. That will remove those rows from your partition, and thus from the total that is considered in the percent of total calculation. By hiding the Fails instead of filtering them, you keep them in the partition but don't show them in the data view.

JasperReports grouping changeable by user

I have no idea if this is possible or not but I'm trying figure out if it is possible to use iReport Designer to create reports where the user viewing the report is able to control the grouping.
For example I would like the user to be able to re-order the grouping and also change to which degree the report is grouped (only on one field or on multiple ones).
I don't mean SQL grouping btw, I mean for example grouping by Account and then Agent:
| Account | Agent | Invoice | Total |
+----------+---------+----------+-------+
| Account1 | | | |
| | Joe | | |
| | | Invoice2 | $600 |
| | | Invoice1 | $300 |
| Account2 | | | |
| | Sam | | |
| | | Invoice4 | $120 |
| | | Invoice7 | $230 |
| | Joe | | |
| | | Invoice3 | $200 |
+----------+-- ------+----------+-------+
And what I'm trying to figure out is, can you use iReport to make this grouping dynamic? That is, that the user might want to group by Agent first and Account second and rather than have one report for each grouping it'd be nice if there was a way of doing this with iReport.
Yes, it should be possible to create reports like that. But depending on your exact needs it may not be practical (as Alex K indicated).
If you take only your example of grouping on Account then Agent or grouping on Agent then account, it would be simple. Have a parameter that let's the user specify this choice. It would probably be a drop down list. Then in the report you would have fields like this:
Today's version: $F{Account} and $F{Agent}
Dynamic version: $P{AcctFirst} ? $F{Account} : $F{Agent} and $P{AcctFirst} ? $F{Agent} : $F{Account}
Likewise, the group definition would need to include the new AcctFirst param.
But it won't extend nicely. What if the 2 fields are different data types? What if you want to let the user choose from 3 or 4 or N fields? Each of those is solvable... but the report becomes exponentially more complex.
By the way, it's relatively common request. You'll see features like this make their way into JasperReports. But for now it's a tough one.