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.
Related
I'm trying to create a top3 ranking from a data table varying metrics but each time I get the wrong order from the cuberankedmember, usually misplacing ranks 2 and 3.
The data I'm mostly focused on is regarding sales revenue. Power pivot sums all sales by store, quite straight forward.
From this I use a cubeset formula that captures store name, filtered by a month and year, which the user types in as any day for the month, and set the measure which to sort by (NTS) (code 1).
The cuberankedmember selects the cubeset and defines the position (code 2).
Then the cubevalue selects as members the cuberankedmember, filters once again month and year, then pulls in the measure (code 3).
E4 is the date
Code1 (cell C21):
=CUBESET("ThisWorkbookDataModel";
"NONEMPTY([Store_Dict].[Nome_DSR].children,
([Calendar].[Year].[All].["&YEAR($E$4)&"],
[Calendar].[Month Number].[All].["&MONTH($E$4)&"]))";
"Ranking";
2;
"[Measures].[NTS]")`
`Code2` (cell `D22`):
`=CUBERANKEDMEMBER("ThisWorkbookDataModel";$C$21;1;"a")
`C21` is the `CUBESET` formula
Code3:
CUBEVALUE("ThisWorkbookDataModel";
$D22;
"[Calendar].[Month Number].["&MONTH($E$4)&"]";
"[Calendar].[Year].["&YEAR($E$4)&"]";
"[Measures].[NTS]")
Actual Result:
Ranking Store NTS
1 a 606
2 c 425
3 b 428
Expected result:
Ranking Store NTS
1 a 606
2 b 428
3 c 425
As an athlete I want to keep track of my progression in Excel.
I need a formula that looks for the fastest time ran in a given season. (The lowest value in E for a given year. For 2017, for example, this is 13.32, for 2018 12 and so on.
Can you help me further?
Instead of formula you can use PIVOT
Keep the Year in Report Filter and Time into Value. Then on value field setting select min as summarize value by.
So every you change the year in the Filter the min value will show up.
=AGGREGATE(15,6,E3:E6/(B3:B6=2017),1)
15 tell aggregate to sort the results in ascending order
6 tells aggregate to ignore any errors such as when you divide by 0
E3:E6 is your time range
B3:B6 is you Year as an integer.
B3:B6=2017 when true will be 1 and false will be 0 (provide it goes through a math operation like divide.
1 tells aggregate to return the 1st value in the sorted list of results
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
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.
I'm working on an excel sheet which has a simple structure like this.
Date | Order
-----------------------
08-15-2014 | 84
08-16-2014 | 50
08-17-2014 | 68
08-17-2014 | 78
08-18-2014 | 23
Here, in a separate column I'd like to calculate the sum of Orders by week days(Sunday, Monday and so on). Meaning, I want to see how many Orders received on Sunday, Monday etc.
So far I have come up with this non working formula.
=SUM(LOOKUP(1, WEEKDAY(date_column), order_column))
This was example for summing all order received on Sunday. And, yes Date column is in DateTime Data type so that shouldn't be a problem.
Thanks.
Consider adding a new column after the dates, representing the day values. So in column B you might have something like =TEXT(WEEKDAY(A2),"ddd").
Then if you wanted to sum up order numbers by day, you could use an equation like =SUMIF(B1:B5,"Sun",C1:C5) where column B has the day values and column C has the order numbers.
To show an example (with headers, etc):