What I am trying to do is simply replicate an excel sheet on Tableau. However, my worksheet shall contain many columns having been calculated using other columns. Calculating a field is not much in Tableau I understand but I want to see the changes happening in the calculated field as one enters the data in the parent field on the dashboard directly. For example I put up the following data on Tableau:
x y(=x*5) z(=x+10)
1 5 11
2 10 12
3 15 13
4 20 14
5 25 15
I would like to see the values of y and z change automatically as the values of x are fed in directly on the dashboard.
I am not able to figure out how to accomplish this on tableau. Would be highly obliged on any help extended. Thanks in Advance.
I know its late but if you still need this to answer then here is my speculations. I am assuming this is how you want your table to be:
| Column X | Column Y| Column Z | A | B | C | ... |
-------------------------------------------------------
| 2 | 10(2*5) | 12(2+10) | 2 | 4 | 1 | ... |
| 4 | 20(4*5) | 14(4+10) | 3 | 1 | 3 | ... |
| 8 | 40(8*5) | 18(8+10) | 6 | 0 | 9 | ... |
| . | . | . | . | . | . | ... |
| . | . | . | . | . | . | ... |
-------------------------------------------------------
You can create calculated fields for ColumnY and ColumnZ . In calculated columns you can you use lookup to find value in a particular column (here ColumnX) and perform calculations on it.
Here is how you create your calculated column:
ColumnY
LOOKUP(SUM(ColumnX),0) * 5
and
ColumnZ
LOOKUP(SUM(ColumnX),0) + 10
Have a look at this LOOKUP function Lookup Table calculation function
Regards
You are essentially talking about parameters. A complete detailed article can be found here
Parameters are dynamic values that can replace constant values in
calculations and can serve as filters. For example, you might have a
calculated field that returns True if Sales are greater than $500,000,
and otherwise returns False. Using a parameter, you can replace the
constant value of $500,000 in the calculated field with a parameter
than you can change dynamically using the Parameter control.
In your case, you can simply create a parameter X, that will be entered by user on the fly, and then in turn use x in the calculations of y and z, thus accomplishing your requirements.
If input is of concern to you than Tableau also enables you to create user based input into your parameters. You can create columns that run off these input, such as Column 1 = X (Parameter 1) * Y (Parameter 2)
To set this up create the parameters, name them, and define their input ranges. For example say Parameter 1 can take integers from 1-1000. Then do the same for Parameter 2.
Next create a calculated field where field = X*Y
Do this for as many variables (parameters) and as many equations (columns) as you want! there you go, the dynamic table.
Related
I am trying to set up a table that will allow for very quick classification of sites across about 50 different characteristics. The method I have thought of but am unsure if it's possible is as follows.
Worksheet A: the raw data about 100R x 50C with each cell
describing a characteristic of that row where the last column is the
overall classification.
Worksheet B: a table of about 5R x 50C with the columns
corresponding to the columns in Worksheet A.
A row of Worksheet B would look something like:
* | * | * | 1 | * | 3 | * | Y | * | ... | * | * | * |
And a row from Worksheet A that corresponds with this data would look something like:
A | B | C | 1 | 5 | 3 | Z | Y | 1 | ... | F | 2 | X | High Priority
Where the asterisks indicate a wildcard where I don't care what the content is. All of the other cells would be required conditions. Then I was thinking of applying an array formula on the last column to get the classification. Something like:
{=IF(AND(A2:BV2='Worksheet B'!$A$2:$BV$2), "High Priority", "Low Priority")}
But Excel takes the asterisks as literal string content and evaluates it as FALSE.
Is there a way to make this work? Or an alternative method that would be just as simple to implement?
I got to the bottom of it with a reasonably elegant solution. Please post criticisms if there is a situation where this won't work.
={IF(SUM(IF(A2:BV2='Worksheet B'!A2:BV2,0,1))=COUNTIF('Worksheet B'!A2:BW2,"x"),"Top Priority", "Low Priority")}
Where x is for those cells in which I don't care about the outcome. So instead of "*", I am using "x" in the cells above such that Worksheet B is more like:
x | x | x | 1 | x | 3 | x | Y | x | ... | x | x | x |
If anyone is interested, the formula works by counting all of the mismatched elements and checking them against the number of cells with "x" in the result. If these two numbers are equal, the number of mismatches is equal to the number of cells we don't care about.
I'm sure i have seen this done with a short formula but i am struggling to remember how to do it.
I am trying to find where a date falls in an interval and sum another column, from that point in the interval, to the end of all specified date intervals.
So, in the image below the intervals are in columns D and E and the date to find is in cell F1 i.e. 12/12/2016.
I want to find where 12/12/2016 falls within the ranges and sum column F accordingly i.e. 12/12/2016 - 13/12/2016 (2 days) and then all intervals after will be 2 + 6+2+1+3 = 14. I am returning this result in cell J14.
I have used the idea of histograms to calculate this currently, but the formula is large and unwieldy, and i just know i have seen a similar question, somewhere on SO but can't find it, that does this with SUMPRODUCT and OFFSET only. I guess FREQUENCY could also be used.
So what i have currently is:
=SUMPRODUCT(OFFSET(F6,MATCH(TRUE,OFFSET(E6,0,0,COUNT(E6:E1048576),)>F1,0)-1,0,COUNTA(F6:F1048576),))-(F1-OFFSET(D6,MATCH(TRUE,OFFSET(E6,0,0,COUNT(E6:E1048576),)>F1,0)-1,,,))
Where, if i broke it down into stages, i find which bucket (range) has the target value:
={MATCH(TRUE,OFFSET(E6,0,0,COUNT(E6:E1048576),)>F1,0)}
I calculate the distance into the range with:
=F1-OFFSET(D6,H13-1,,,)
And i sum from this point until the end of the range with:
=SUMPRODUCT(OFFSET(F6,H13-1,0,COUNTA(F6:F1048576),))-I13
So, can anyone help me with a shorter more efficient formula please?
Data:
| Start of measurement | 12/12/2016 | |
|----------------------|------------|----------------|
| | | |
| | | |
| | | |
| From | To | Number of days |
| 13/11/2016 | 17/11/2016 | 5 |
| 10/12/2016 | 13/12/2016 | 4 |
| 03/02/2017 | 08/02/2017 | 6 |
| 06/12/2017 | 07/12/2017 | 2 |
| 09/12/2017 | 09/12/2017 | 1 |
| 12/12/2017 | 14/12/2017 | 3 |
This should work for you:
=SUMIF(E6:E11,">="&F1,F6:F11)-F1+INDEX(D6:D11,MATCH(F1,D6:D11))
How about this?
=SUMIFS(F6:F11,D6:D11,">="&F1)+MINIFS(E6:E11,E6:E11,">="&F1)-F1+1
The SUMIFS() gives the 6+2+1+3 part and the MINIFS() - F1 + 1 gives the 2 part.
Note that the ___IFS() functions are more recent and not available in older versions of Excel.
I have a table that looks the following:
| A | B | C |
| 40 | 1 | 1 |
| 180 | 2 | 2 |
| 34 | 1 |
| 2345 | 3 |
| 23 | 1 |
| 1 | 2 |
| 4354 | 3 |
| 2 | 2 |
| 343 | 4 |
| 2 | 2 |
| 45 | 1 |
| 23 | 1 |
| 4556 | 3 |
I want to get the sum of all fields in A where B is neither 1 nor 2 or any other value from colum C. This column contains the values of B where values from A should not be considered for the sum.
I do not know which values B might contain, those values are random and could grow larger, I just wanted to make the example small. My current solution is
{=SUMIF(B1:B13,C1:C2,A1:A13)}
so i can set the lines that should be excluded from the sum in column C. Unfortunately, the current solution does not solve my problem but something different -- it sums up the corresponding entries by value in C. My preferred solution would look something like
=SUMIF(B1:B13,"<>{1, 2}",A1:A13)
=SUMIF(B1:B13,"<>"&C1:C2,A1:A13)
if that were possible (it isn't). I would like to have:
a field (with a list, for example) or column where i can put in the values of B that I do not want to be part of the sum over A.
a method that works with Open Office as well as Excel. I prefer an OO solution.
You could use an array formula so that you can multiply each value in A with a condition. That condition can be any valid Excel formula, so, for instance, you could use MATCH to test if the B value occurs in C:
=SUM((A1:A13)*ISNA(MATCH(B1:B13,$C:$C,0)))
The ISNA function returns TRUE when the match fails, which in a multiplication is used as a numerical value 1. FALSE will make the product 0.
Make sure to enter this as an array formula with Ctrl+Shift+Enter
I am no excel expert and after some research have come up with this formula to look at two sets of the same data from different times. It then displays new entries that are in the latest list of data but not in the old list.
This is my formula:
{=IF(ROWS(L$4:L8)<=(SUMPRODUCT(--ISNA(MATCH($E$1:$E$2500,List1!$E$1:$E$2500,0)))),
INDEX(E$1:E$2500,
SMALL(IF(ISNA(MATCH($E$1:$E$2500&$F$1:$F$2500,List1!$E$1:$E$2500&List1!$F$1:$F$2500,0)),
ROW($F$1:$F$2500)-ROW($F$1)+1),ROWS(L$4:L8))),"")}
Are there any optimisation techniques I could employ to speed up the calculation?
As requested
Some example data(link to a spreadsheet):
https://docs.google.com/file/d/0B186C84TADzrMlpmelJoRHN2TVU/edit?usp=sharing
On this scaled down version its more efficent but on my actual sheet with a lot more data it is slowed.
Well, I was playing around a bit and I think that this works the same, and without the first IF statement:
=IFERROR(INDEX(A$1:A$2500,SMALL(IF(ISNA(MATCH($A$1:$A$2500&$B$1:$B$2500,List1!$A$1:$A$2500&List1!$B$1:$B$2500,0)),ROW($B$1:$B$2500)-ROW($B$1)+1),ROWS(F$2:F2))),"")
That part in your sample data:
ROWS(F$2:F2)<=(SUMPRODUCT(--ISNA(MATCH($A$1:$A$2500,List1!$A$1:$A$2500,0))))
As I understood it, it only sees to it that the row number in which the formula is entered is lower than the number of 'new' items, but it doesn't serve any purpose because when you drag the formula more than required, you still get errors instead of the expected blank. So I thought it could be removed altogether (after trying to substitute it with COUNTA() instead) and use an IFERROR() on the part directly fetching the details.
EDIT: Scratched that out. See barry houdini's comment for the importance of those parts.
Next, you had this:
ROW($B$1:$B$2500)-ROW($B$1)+1
-ROW($B$1)+1 always returns 0, so I didn't find any use to it and removed it altogether.
It's still quite long and takes some time I guess, but I believe it should be faster than previously by a notch :)
A relatively fast solution is to add a multi-cell array formula in a column alongside List 2
{=MATCH($A$1:$A$16,List1!$A$1:$A$11,0)}
and filter the resultant output for #N/A.
(Or see Compare.Lists vs VLOOKUP for my commercial solution)
Array formula is slow. When you have thousands of array formula, it will make the speed very slow. Thus the key will be to avoid any array formula.
The following will be my way to achieve it, using only simple formula. It should be fast enough if you only have 2500 rows.
Column F and H are "Keys", created by concatenating your 2 columns (E and F in your original formula)
Assuming the first line of data is on row 3.
Data:
| A | B | | D | E | F | | H |
| index | final value | | ID | exist in Old? | Key (New) | | Key (Old) |
--------------------------------------------------------------------------------
| 1 | XXX-33 | | 0 | 3 | OOD-06 | | OOC-01 |
| 2 | ZZZ-66 | | 0 | 1 | OOC-01 | | OOC-02 |
| 3 | ZZZ-77 | | 1 | N/A | XXX-33 | | OOD-06 |
| 4 | | | 1 | 4 | OOE-01 | | OOE-01 |
| 5 | | | 1 | 2 | OOC-02 | | OOF-03 |
| 6 | | | 2 | N/A | ZZZ-66 | | |
| 7 | | | 3 | N/A | ZZZ-77 | | |
Column E "exist in Old?": test if the new key (Column F) exists in the old list (Column H)
=MATCH(F3, $H$3:$H$2500, 0)
Column D "ID": to increment by one whenever a new item is found
=IF(ISNA(E3), 1, 0)+IF(ISNUMBER(D2), D2, 0)
the 2nd part of ISNUMBER is just for the first row, where just using D2 can cause an error
Column A "index": just a plain series starting from 1 (until the length of new list Column F)
Column B "final value": to find the new key by matching column A to Column D.
=IF(A3>MAX($D$3:$D$2500), "", INDEX($F$3:$F$2500, MATCH(A3, $D$3:$D$2500, 0))
This column B will be the list you want.
If it is still too slow, there exists some dirty tricks to speed up the calculation, e.g. by utilizing a sorted list with MATCH( , , 1) instead of MATCH( , , 0).
First off, I'd like to do this without VB if possible, so I don't have to go through the hassle of teaching recipients how to enable macros.
Now, I believe what I'd like to do is simple, but the answer may be complex formula-wise. I'm trying to list out in new columns the values from a specified column in rows which have matching values from two other columns. Sounds tricky I'm sure, but an example should help immensely...
Say I have the following data:
------------------
| sts | pos | bye |
------------------
| 0 | QB | 8 |
| 2 | WR | 3 |
| 2 | QB | 10 |
| 0 | QB | 4 |
| 2 | QB | 7 |
| 0 | WR | 11 |
| 2 | WR | 9 |
| 2 | QB | 5 |
------------------
That's my source. I want to list out the bye value from all rows that have sts = 2, for each respective pos. In other words, from the source data above I'd want to see the following result set:
--------------------------
| pos | byes |
--------------------------
| QB | 10 | 7 | 5 | |
| WR | 3 | 9 | | |
--------------------------
...because those are the bye values in the rows with sts = 2 and pos equal to the corresponding pos in the result table.
Again, I'd like to avoid macros if possible, and just use a formula in the bye cells of the results table.
Hopefully that makes enough sense for you to take a stab at it. Thanks!
FOLLOW-UP:
#Richard-Morgan I attempted to use your formula but can't get it to work. Here is a screenshot of my actual spreadsheet so we can use real cell references:
So sts is B2:B303, pos is D2:D303, and bye is E2:E303. So then I'd like to list out the byes in columns U thru Y. It looks like your answer, if I'm smart enough to implement it, will get me what I need, so any assistance you can provide to get me to the finish line is greatly appreciated!
Something along the lines of the following could be used:
{=INDEX(tbl, SMALL(IF(COUNTIF(G$3, $A$2:$A$9)
*COUNTIF(G$4, $B$2:$B$9), ROW(tbl)-MIN(ROW(tbl))+1), ROW($C1)), COLUMN($C1))}
where the A column is sts, B column is pos, and C column is bye. The variable tbl is the range of data (not the headers). G$3 would be the sts filter and G$4 is the pos filter.
Copy the array formula DOWN to find all the matching byes; #NUM! will appear after finding no more matches. If this bothers your users, you can add an ISERROR or a tricky conditional format that makes the text white on white.
You can then copy over the formula to the next column and enter new filter values.
G H
sts Search 2 2
pos Search QB WR
10 3
7 9
5 #NUM!
#NUM!#NUM!
If your users are comfortable with pivot tables, using them would be much easier, I would think.
EDIT
Making the formula "transpose" is a bit tricky and I am not having any breakthrough on how to fix that. However, if you want to manually edit the column formulas, here is what you want.
(I made the assumption that S is the sts filter. Maybe you're just doing a count there, but I didn't see where you enter the filter for sts. If S isn't the sts filter, update the formulas to point to where sts is 2 or whatever.)
U2:
{=INDEX(tbl, SMALL(IF(COUNTIF($S2, $B$2:$B$303)*COUNTIF($R2, $D$2:$D$303),
ROW(tbl)-MIN(ROW(tbl))+1), ROW($D$1)), COLUMN($D$1))}
V2:
{=INDEX(tbl, SMALL(IF(COUNTIF($S2, $B$2:$B$303)*COUNTIF($R2, $D$2:$D$303),
ROW(tbl)-MIN(ROW(tbl))+1), ROW($D$2)), COLUMN($D$2))}
etc.
This allows the cells to be copied down.
I am sure there is a way to INDIRECT the ROW/COLUMN, but I ran out of time to look at this at the moment.
EDIT 2
If you put a simple number increment somewhere, let's say U1 has 1, V1 has 2, W1 has 3, etc., you could use the following:
{=INDEX(tbl, SMALL(IF(COUNTIF($S2, $B$2:$B$9)*COUNTIF($R2, $D$2:$D$9),
ROW(tbl)-MIN(ROW(tbl))+1), U$1), COLUMN($D$1))}
This will copy down and across.
This sounds like a job for pivot tables and go to special. You need to add an ID # column though. Here is one way you could do it:
Then once the blanks are selected using go to special you just need to delete them and shift cells left.
Good Luck.
OK I figured out a way to get my desired results. It isn't the cleanest or best way, but it achieves my goal of listing the results horizontally, and avoids macros or pivot tables.
I use a hidden worksheet to list out all the pos and sts values, concatenated as a single value. So...
sts | pos | bye
----------------------
2 | QB | 8
2 | RB | 5
2 | QB | 11
0 | WR | 7
. . .
...becomes....
D | E
-----------
5 | 2QB | 8
6 | 2RB | 5
7 | 2QB | 11
8 | 0WR | 7
. . .
Then, I have a "shadow" results area that mimics the results area on my front-page worksheet. It looks like so:
G | H | I | J | K
-----------------------------
5 | QB | | | | |
6 | RB | | | | |
7 | WR | | | | | . . .
In H5:H7, I have the following formula:
=IFERROR((ADDRESS(MATCH("2"&$G5,$D$5:$D$305,0)+4,COLUMN($E5),4)),"")
This returns the first cell reference it finds in the concatenated column that starts with 2 and ends with the value in column G (e.g. the formulas in row 5 are looking for "2QB").
Then, in I5:n7 I have the following modified formula:
=IFERROR(ADDRESS(MATCH("2"&$G5,INDIRECT(ADDRESS(ROW(INDIRECT(H5))+1,4)&":$d$"&MAX(305,ROW(INDIRECT(H5))+1)),0)+ROW(INDIRECT(H5)),COLUMN($E5),4),"")
The reason I modify the subsequent columns is to change the range in which the formula is looking for its value to start at the next row after the previously found value. For example, with the data above, the formula in H5 would look for "2QB" in D5:D*n*, and return the first row it finds and attach it to column E, which would be E5.
The formula in I5 would then look for "2QB" starting in D*6* instead of D5, a row after the row referenced in H5's result.
Hopefully that made sense.
So what I end up with in my hidden worksheet is this:
G | H | I | J | K
-----------------------------
5 | QB | E5 | E7 | | |
6 | RB | E6 | | | |
7 | WR | | | | | . . .
Then, on my front page worksheet, I simply get the values (the bye) referenced by the cells in H5:*n*7 using:
=IFERROR(INDIRECT(lookups!H5),"")
...which gives me my final result:
G | H | I | J | K
-----------------------------
5 | QB | 8 | 11 | | |
6 | RB | 5 | | | |
7 | WR | | | | | . . .
Like I said, it's totally convoluted, but it works, and I can always refine it later if I figure out how. :) Thanks to you who took a swing at this seemingly complex problem for me! I'm sure your answers work beautifully as well.