Spotfire over function - previous date with multiple categories - spotfire

I'd like to calculate a value difference between two rows that is classified by Type and ID and is sorted by a date column. See example data table. Note that column "Calculated" shows the current results, while column "Expected" shows the results I would like to achieve.
ID Type Date ValueA ValueB ValueC Calculated Expected
1 A 8/15/2017 38.11
1 A 8/15/2017 78.10 39.99
1 A 8/22/2017 110.24 32.14
1 B 8/22/2017 20
1 B 9/16/2017 10
1 A 9/16/2017 101.13 -9.11
2 C 8/17/2012 90
2 A 8/18/2012 863.25
2 B 8/18/2012 15
2 A 8/19/2012 952.35 89.1 89.1
2 B 8/19/2012 20
I tried the following custom expression, but it seems to calculate a difference value only for cases where there is a consecutive date for a given ID.
Case
when [Type]="A" then [Value] - Max([Value]) over (Intersect([ID],Previous([Date])))
else NULL
The expression is an attempt to filter to Type "A" for the OVER statement, such that the previous date is the previous date only for values categorized as Type "A". However, it seems to consider the previous date as NULL if is not a consecutive date (i.e. prior day). See "Calculated" in table above for results from this expression.
I also tried to add Type to the Intersect statement, e.g. Intersect([ID],[Type], Previous([Date]), but I get a similar result.

does
[value] - max[value] over (intersect([Type],[ID],previous([Date])))
give you the calculated column you want
Edit:
I was able to almost match your expected column using this formula (previousperiod instead of just previous), but the first two rows are the same date so it is not an exact match.
formula

Related

Count of Excel based on 2 column criteria and counting the 3rd column

I need a count of how many date items fall within Data 1 & Data 2
ie:
x-1 will have a count of 2
x-2 will have a count of 1
-x-3 will have a count of 2
-y-1 will have a count of 2
What would be the best way to go abouts when approaching this?
Data 1
Data 2
Date
x
1
Date 1
x
1
Date 1
x
1
Date 2
x
2
Date 3
x
2
Date 3
y
1
Date 1
y
1
Date 1
I see only one way to interpret with the available information:
To count the number of times Date_to_test falls within Date_1 and Date_2 (screenshot below, sheet here), you could use either the sum or something like a countifs (with interim calc):
sum approach
=SUM(1*($C$2:$C$11<=$B$2:$B$11)*($A$2:$A$11<=$C$2:$C$11))
countifs + interim calc
helper
=1*(C2<=B2)*(A2<=C2)
(additional column, drag down)
countifs
=COUNTIFS($D$2:$D$11,1)
Screenshot
Alternative
as for the 'sum' approach, sumproduct variants (e.g. =SUMPRODUCT(1*($C$2:$C$11<=$B$2:$B$11),1*($B$2:$B$11>=$A$2:$A$11))) are calculation/memory intensive
despite the countifs + helper approach containing more 'visible' data - these values need only be calculated once, the countifs can then be determined independently (assuming no updates to the helper column) - thus making it more memory/calculation efficient depending upon your calculation mode, screen-updating preferences
Caveat
if, by some misfortune re: interpreting your question, you are referring to some other means of establishing whether "date items fall within Data 1 & Data 2", then without knowing what this is, there very low likelihood of being able to guess this correctly

Why does the DAX formula in my calculated column use propagation to filter in one instance and not in another?

Suppose I have a couple of tables:
fTransactions
Index ProdID RepID Revenue
1 1 1 10
2 1 1 20
3 2 2 30
4 2 2 10
dSalesReps
RepID RepName CC1 CCC2
1 joe 40 70
2 sue 30 70
3 bob 70
CC1 contains a calculated column with:
CALCULATE(SUM(fTransactions[Revenue]))
It's my understanding that it's taking the row context and changing to filter context to filter the fTransaction table down to the RepID and summing. Makes sense per an sqlbi article on the subject:
"because the filter context containing the current product is automatically propagated to sales due to the relationship between the two tables"
CC2 contains a calculated column with:
SUMX(fTransactions, CALCULATE(SUM(fTransactions[Revenue]))
However, this one puts the same value in all the columns and doesn't seem to propagate the RepID like the other example. The same sqlbi article mentions that a filter is made on the entire fTransactions row. My question is why does it do that here and not the other example, and what happened to the propagation of RepID?
"CALCULATE places a filter on all the columns of the table to identify a single row, not on its row number"
A calculated column is created in a loop: power pivot goes row by row and calculates the results. CALCULATE converts each row into a filter context (context transition).
In the second formula, however, you have 2 loops, not one:
First, it loops dSalesReps table (because that's where you are creating the column);
Second, it loops fTransactions table, because you are using SUMX function, which is an iterator.
CALCULATE function is used only in the second loop, forcing context transition for each row in fTransactions table. But there is no CALCULATE that can force context transition for the rows in the dSalesReps. Hence, there is no filtering by Sale Reps.
Fixing the problem is easy: just wrap the second formula in CALCULATE. Better yet, drop the second CALCULATE - it's not necessary and makes the formula slow:
CCC2 =
CALCULATE(
SUMX(fTransactions, SUM(fTransactions[Revenue]))
)
This formula is essentially identical to the first one (the first formula in the background translates to the second one, SUM function is just a syntax sugar for SUMX).
You could also write the formula as:
CC2 = SUMX( RELATEDTABLE( fTransactions ), fTransactions[Revenue] )
or
CC2 = SUMX( CALCULATETABLE( fTransactions ), fTransactions[Revenue] )
The key is that fTransactions as the first argument of SUMX needs to be filtered for each SalesRep (i.e. on the current row). Without the filter then you are just iterating the entire fTransactions table for each SalesRep. Somehow SUMX needs to know you just want the fTransactions for the SalesRep whose revenue you are trying to compute.

DAX returning value based on SUM of multiple rows in other table

Good evening all!!
Here's a fun one. I've been pouring through some other posts and it feels like there are many permutations of this scenario but none that span tables, so I'm looking for some input.
Consider the following:
Table A has two fields: ID and TYPE. TYPE will be our value to populate.
ID Type
1
2
3
Table B has two fields: ASSOCIATED ID and HOURS.
Associated ID Hours
1 24
1 0
2 10
2 38
3 50
3 25
The requirement is to return a value of "LESS THAN 25" or "GREATER THAN 25" for TYPE in TABLE A based on the SUM of the HOURS in TABLE B for the ASSOCIATED ID. Ex: ASSOCIATED ID "1" in TABLE has value 24 and 0 for a sum of 24, returning "LESS THAN 25" for TYPE in item ID 1 in TABLE A.
Any and all suggestions will be attempted, thank you so much to the community for taking a look.
Make sure you have a relationship between the two tables by using the ID. Then enter this formula into a column in the ID table:
Type:=if(calculate(sum(TableB[Hours]))>25,"25 or More","Less than 25")
Try this one on 1-TYPE: (I am considering A1 Cell as the beginning of your table for both table, just place the real position)
=IF(SUMIF(TableB!$A$2:$A$7,"="&A2,TableB!$B$2:$B$7)>=25,"GREATER THAN 25","LESS THAN 25")
Then drag it down.

Excel Formula - get the date of a maximal value within a list

I have a rather big (long) table and need to do something quite simple but I'm currently with a sort of blackout...
Imagine that you have:
Date 1 Value 1 Date 2 Value 2 Date 3 Value 3 Date of MAX
... ... ... ... ... ... ????
I want to deploy in ???? a formula that will result in the date at which the maximal value (between Value 1...3) was registered. For instance:
Date 1 Value 1 Date 2 Value 2 Date 3 Value 3 Date of MAX
20160501 10 20160722 47 20161002 9 20160722
meaning, the Date of MAX is of Date 2 because that was the date at which the MAX was measured.
Thanks in advance.
You could do a more general solution using offset:-
=MAX(N(OFFSET(D2,0,COLUMN(A:D)*3)))
to find the largest value - put this in (say) R2.
Then find a match for it and pick out the corresponding date:-
=OFFSET(C2,0,MATCH(R2,N(OFFSET(D2,0,COLUMN(A:D)*3)),0)*3)
assuming the dates and values are every third column.
These are array formulae and must be entered with CtrlShiftEnter
If the last value really was in P21 you would have to give a row offset as well as a column offset.
OK, I found a dirty but simple solution (don't know why I didn't think of it at first):
=IF(G2>=MAX(G2,J2,M2,P21),F2,IF(J2>=MAX(G2,J2,M2,P21),I2,IF(M2>=MAX(G2,J2,M2,P21),L2,O2)))
where the pairs (4 of them) are at FG, IJ, LM, OP. Not elegant but does the job.

Compare values previous date and second previous date in PowerPivot

I'm new to PowerPivot and DAX. I've followed some on-line tutorials. Now I have a small problem that I can't solve. I have the following data:
Date Instrument Value
2016-07-27 A 100
2016-07-27 B 98
2016-07-26 A 102
2016-07-25 B 99
For each date I would like to calculate the difference (Profit/Loss) in Value between most recent date and second most recent date. For the data above it would be the following:
Date Instrument Value Profit/Loss
2016-07-27 A 102 2 ([Val. inst. A 2016-07-27]-[Val. inst. A 2016-07-26])
2016-07-27 B 98 -1 ([Val. inst. B 2016-07-27]-[Val. inst. B 2016-07-25])
2016-07-26 A 100
2016-07-25 B 99
I have tried with DAX to find the second largest date using =EARLIER([Date])but haven't managed to get it to work. With the second largest date I would maybe be able to find the Value corresponding to that date. Any suggestions how this could be solved?
In the end I came up with a solution in three steps (the steps can be combined into one step). First I rank all the dates, with the most recent being 1 and the second most recent being 2. After that I retrieve the Value for the second most recent day for each row. Finally I calculate the difference between the Values current row and the Value for the second most recent day compared to that row's date.
To rank the dates I used the following:
=RANKX(FILTER(ALL(table);EARLIER([Instrument])=[Instrument]);[Date];;FALSE())
Explanation to what I think the DAX formula is doing. RANKX works by taking a table and then rank the values in a column in that table. Above I've used a filtered table as the table. The filtered table creates a new table for each row containing only the same instrument as the instrument for that particular row. For the first row, the filtered table would look like below.
Date Instrument Value
2016-07-27 A 100
2016-07-26 A 102
The dates in that filtered table is then ranked.
Date Instrument Value Rank
2016-07-27 A 100 1
2016-07-26 A 102 2
Using the Rank I then pull out the second most recent dates Value for each row based on the current row's Rank-1.
Value second most recent date = CALCULATE(MAX([Value]);FILTER(table;EARLIER([Instrument])=[Instrument] && [Date Rank]= EARLIER([Date Rank]))
Finally I calculate the difference:
PnL = [Value] - [Value second most recent date]
I'm not sure what EARLIER is doing but I think it is some sort of iterative process.

Resources