SpotFire - How to get cumulative percentage - spotfire

I need to obtain Cuml % in Spotfire; how to do? Please refer the below data-set
Data Set

You'll want to use the OVER function. I re-created your data table, then inserted three calculated columns:
ActualCuml = Sum([Actual]) OVER (AllPrevious([Day]))
PlannedCuml = Sum([Planned]) OVER (AllPrevious([Day]))
CumlPct = [ActualCuml] / [PlannedCuml]
The first two calculated columns are your rolling sums for Actual and Planned, and then the third column just divides those two new columns to get the cumulative percentage.
You could just insert a single calculated column and use the expressions from the first two as the division factors:
Sum([Actual]) OVER (AllPrevious([Day])) / Sum([Planned]) OVER (AllPrevious([Day]))

Related

EXCEL - Dual VLOOKUP and Interpolation

I have a table on Excel with data as the following:
Meaning, I have different JPH based on the %SMALL unit and the number of active stations.
I need to create a matrix like the following (with %SMALL on horizontal and STATIONS on vertical axes):
And the formula for each cell should:
Take the input of Stations (column "B")
Check, for that specific Stations number, the amount of data on the other table (like make a filter on STATIONS for the specific number)
Perform an VLOOKUP for checking the JPH based on the %SMALL value on row 2
Interpolate for the exact JPH value, if not found on table
For now, I was able to create the last part (the VLOOKUP and the interpolation), with the following:
=IFERROR(VLOOKUP(C2;'EARLY-STATIONS'!$F:$H;3;FALSE);AVERAGE(OFFSET(INDEX('EARLY-STATIONS'!$H:$H;MATCH(C2;'EARLY-STATIONS'!$F:$F;1));0;0;2;1)))
The problem I'm facing is than with this, the calculation is not checking the number of stations, so the Iteration is not accurate.
Unfortunately I cannot use VBA macros to solve this.
Any clue?
This is an attempt because more clarity is needed in terms of all possible scenarios to consider, based on different input data and how to understand the "extrapolation" process. This approach understands as extrapolation the average of two values (lower and greater), but the idea can be customized to any other way to calculate it. Per tags listed in the question I assume there is no Excel version constraint. This is O365 solution:
=LET(sm, A2:A10, st, B2:B10, jph, C2:C10, smx, F1:J1, sty, E2:E4, NULL, "",
GETLk, LAMBDA(x,y,mode, FILTER(jph, (st=y)
* (sm = INDEX(sm, XMATCH(x, sm, mode))), NULL)),
GET, LAMBDA(x,y, LET(f, FILTER(jph, (jph=GETLk(x,y, 1))
+ (jph=GETLk(x,y, -1)), NULL), IF(#f=NULL, NULL, AVERAGE(f)))),
HREDUCE, LAMBDA(yi, DROP(REDUCE("", smx, LAMBDA(ac,x,
HSTACK(ac, GET(x, yi)))),,1)),
DROP(REDUCE("", sty, LAMBDA(ac,y, VSTACK(ac, HREDUCE(y)))),1))
The above formula spills the entire result, I don't think for this case you can use a LOOKUP-like function.
Here is the output:
The highlighted cells where the average is calculated.
Explanation
The main idea is to use DROP/REDUCE/HSTACK/VSTACK pattern to generate the grid. Check my answer to the following question: how to transform a table in Excel from vertical to horizontal but with different length on how to apply it.
We use two user LAMBDA functions to abstract some calculations:
GETLk(x,y,mode), filters jph name based on %SMALL and Stations columns values, based on input values x (x-axis value from the grid), y (y-axis value form the grid) respectively. The third input argument mode, is for doing the approximate search in XMATCH (1-next largest, -1 next smallest). In case the value exist in the input table, XMATCH returns the same value in both cases.
GET(x,y) has the logic to find the value or if the value doesn't exist to calculate the average. It uses the previous LAMBDA function GETLk. We filter for jph values that match the input values (x,y), but we use an OR condition in the FILTER (+), to select both lower or greater values. If the value exist, returns just one value otherwise two values are returned by FILTER (f). Finally if f is not empty we return the average, otherwise the value we setup as NULL.
HREDUCE: Concatenate the result by columns for a given row of the grid. Check the referred question for more information about it.

Comparing two columns and their values and outputting the greater value

I'm trying to compare two columns ("Shows") from different tables and showing which one has the greater number ("Rating") associated with it in another table.
Ignore the operation column above as part of the solution that I'm trying to get, it's just to illustrate for you what I'm trying to compare.
Important note: If the names are duplicated. Compare the matching pair in their corresponding order. (1st with 1st, 2nd with 2nd, 3rd with 3rd etc..) illustrated in the table below:
Thanks
You can try the following in cell F3 for an array solution that spills the entire result at once:
=LET(sA, A3:A6, rA, B3:B6, sB, C3:C6, rB, D3:D6, CNTS, LAMBDA(x,
LET(seq, SEQUENCE(ROWS(x)), MAP(seq, LAMBDA(s,ROWS(FILTER(x,(x=INDEX(x,s))
*(seq<=s))))))), cntsA, CNTS(sA), cntsB, CNTS(sB), eval, MAP(sA, rA, cntsA,
LAMBDA(s,r,c,IF(r > FILTER(rB, (sB=s) * (cntsB=c)), "Table 1", "Table 2"))),
HSTACK(sA, eval))
Here is the output:
Explanation
The main idea is to count repeated show values. We use a user LAMBDA function CNTS, to avoid repetition of the same formula twice. Once we have the counts (cntsA, contsB), we use MAP to iterate over Table 1 elements with the counts and look for specific show and counts to compare with Table 2 columns. The FILTER function will return always a single value (based on sample data). Finally, we prepare the output as expected using HSTACK.
Try-
=IF(INDEX(FILTER($B$3:$B$6,$A$3:$A$6=G3),COUNTIFS($G$3:$G3,G3))>INDEX(FILTER($E$3:$E$6,$D$3:$D$6=G3),COUNTIFS($G$3:$G3,G3)),"Table-1","Table-2")

Calculated column which references its previous value and current value

I have a requirement where I am creating a calculated column. This column needs to use its own previous value and also its current value (i.e. to perform a cumulative calculation).
I know this is possible in Tableau by using the function
PREVIOUS_VALUE(-1)
so I can do something like
x (calc) = sum(x(calc) + PREVIOUS_VALUE(-1))
How can this be performed in Spotfire? In other words, what is the equivalent Spotfire function to
PREVIOUS_VALUE(-1) (from Tableau)
Here is the equivalent implementation on excel. Where [WDVpt2] is the calculated field.
This is done with an OVER function. You can read about them from the Tibco Documentation. The formula you are looking for is:
(Sum([x]) over (AllPrevious([x]))) - [x]
Uses all nodes, including the current, from the start of the level.
This can be used to calculate the cumulative sum.
I was able to achieve this by the following approach. Its a limitation of Spotfire that a calculated column can not refer its value at the previous node.In tableau Lookup and Previous_value supports this feature(not to be confused with Previous() of Spotfire which can be applied on a static column [x] so [X_Calc]= [X_Calc]+ [X_Calc] over(AllPrevious([ROWID])) is not possible
Step1:Create a ROW ID column which is based on perdiod Rowid([YEAR])
Step2:Breaking the result for each row into a separate calculated column so first row value
First(Sum([WDVpt1]) over (AllPrevious([RowID])) - (Sum([WDVpt1]) over AllPrevious([RowID])) * [Policy rate])) over (AllPrevious([RowID])))
Step3: Create columns for remaining periods(3 to 16) by using the previous calculated column Eg:- column for node 3 will use [WDVpt2_Year2] column for node 4 will use [WDVpt2_Year3] and so on Sum((case when [RowID]=2 then [WDVpt1] end) + Min([WDVpt1]) over ([RowID]) - (((case when [RowID]=2 then [WDVpt1] end) + Min([WDVpt2_Year2]) over (intersect([asset class code],[RowID]))) * [Policy rate])) over (AllPrevious([RowID])))
Step4: Write a case statement to generate one single column
case when [RowID]=2 then first([WDVpt2_Year2]) when [RowID]=3 then first([WDVpt2_Year3]) when [RowID]=4 then first([WDVpt2_Year4]) when [RowID]=5 then first([WDVpt2_Year5]) when [RowID]=6 then first([WDVpt2_Year6]) when [RowID]=7 then first([WDVpt2_Year7]) when [RowID]=8 then first([WDVpt2_Year8]) when [RowID]=9 then first([WDVpt2_Year9]) when [RowID]=10 then first [WDVpt2_Year10]) when [RowID]=11 then first([WDVpt2_Year11]) when [RowID]=12 then first([WDVpt2_Year12]) when [RowID]=13 then first([WDVpt2_Year13]) when [RowID]=14 then first([WDVpt2_Year14]) when [RowID]=15 then first([WDVpt2_Year15]) when [RowID]=16 then first([WDVpt2_Year16]) end as [WDVpt2]

Sum up values on distinct rows filter

I need to calculate the total shipping cost for some sales orders. The dataset is as follows:
The issue I have is that although the shipping cost should be taken into account only once per order in the calculation, in the dataset it is repeated for each order item, thus a simple duplicates shipping costs:
=SUM(MyTable[Shipping]) = 90 // wrong value
However what I need is to:
filter the table to only keep 1 line for each order
sum up the shipping
Which should be something like:
=SUMX(FILTER(MyTable,<filter>),MyTable[Shipping]) = 35 // correct value
But I'm struggling to write the <filter>. I found DISTINCT which returns the list of unique order IDs, but not their corresponding row.
Does anybody have any ideas how I could write the filter to calculate shipping properly?
The X functions are non intuitive but very powerful - you are on the right lines.
I would approach this with two measures, the first to sum the shipping cost and divide it by the number of rows for that order. (Key to the second half is the ALL() which opens up the context on the column referenced whilst retaining the other contexts.)
And the second to iterate that measure by order and sum the outcomes.
[Allocated Shipping] =
SUM ( MyTable[Shipping] )
/ CALCULATE ( COUNTROWS ( MyTable ), ALL ( MyTable[Item] ) )
[Iterated Shipping] =
SUMX(VALUES(MyTable[Order]), [Allocated Shipping])
The simplest approach would be to use a Helper column. In E2 enter:
=IF(COUNTIF($A$1:A2,A2)>1,0,1)
and copy down. This will identify the unique values in column A. To sum these unique values, use:
=SUMPRODUCT(--(E2:E9=1)*(D2:D9))
For your data:
The value is 35
Naturally if the data were filtered you would use a variation of the SUBTOTAL() function or an additional helper column.
In a very similar way to Gary's recommendation, you could use (in an additional col - E2):
=IF(COUNTIF($A$2:A2,A2)>1,D2,0)
This will show the cost of the delivery in col E itself. You can then just SUM(E2:E) to see the total cost (35).

PivotTable - Calculate value depending on combination of row labels

WARNING - Using Excel 2011 for Macs, inexperienced user
Hi All,
I have a sheet in Excel with a bunch of categorical fields and some numerical ones as well. Let's say it looks like the following:
I would like to make a pivot table that will display the average click rate (avg_click_rate) of the unique combinations of [year, region], i.e. the combinations of fields in the pivottable's rows section.
For example, the avg_click_rate of [years=5] is:
(0.5*10)/(10 +5 ) + (0.6*5)/(10+5) = 0.53
while the avg_click_rate of [region=north] is:
(0.6*5)/(5+20) + (0.2*20)/(5+20) = 0.28
and the avg_click_rate of [years=5, region=south] is:
(0.5*10)/10 = 0.5
I know I have to make a custom Calculated Field to do this, but for the life of me I cannot figure out how to code the formula. Any help would be seriously, seriously appreciated.
To be clear, my formula would be:
SUM{ (click_rate * number_members) / SUM{number_members} }
where the numerator is a single value for each row included in the unique combination of [year, region], while the denominator is a constant - the total number_members for the unique combination of [year, region].
You should create a new column in your source table:
product = click_rate * number_members
And then create a Calculated Field in the pivot table:
CF = product / number_members
Using AVERAGEIFS:
AVERAGEIFS($C$2:$C$9,$A$2:$A$9,A2,$B$2:$B$9,B2)
EDIT:
You can add up to 127 conditions, see: AVERAGEIFS function
Criteria_range1, criteria_range2, … are 1 to 127 ranges in which
to evaluate the associated criteria.

Resources