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.
I am quite newbie in cognos. I wonder how I can create a variable as percentage from the total.
I have the following table containing a variable named compliant which can either be Y or No.
Y
N
Total
percentage_Y_of_total%
1
3
4
25%
I created the Y and N variable with
case when Complaint_VAR ('Y') then 'Compliant' else 'Non-Compliant' end
My question: How do I create percentage_Y_of_total variable? How do I create a data item as percentage of the total split by case when clause?
Go to query explorer. Tool box. Drag data item to the details to create custom expressions
Use function total and define the scope, let's call the data item Y_Total. For example the expression would look like:
Total(Y for company, year, month)
Create another data item Overal_Total that gets the total rows of data
Create a calculation data item called percentage_Y_of_total% that takes Y_Total divided by Overal_Total
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]
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]))
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).