In PowerBI, I want to compare the value growth of categories (lets take A and B) over time from any starting year. To compare this easily, I am using a line graph with the time on the x-axis and category as a legend. I would like both categories to start at 100% and show the growth relative to that starting point. I then want to be able to use a continuous date slicer to vary the start and end-points of my line graph.
I've created a dummy data to illustrate this
Category, Year, Value
A 2000 5
A 2001 8
A 2002 8
A 2003 10
B 2000 10
B 2001 8
B 2002 12
B 2003 10
Without any date filter, I would like to display years 2000-2003 with the following values for the lines:
A: 100%, 160%, 160%, 200%
B: 100%, 80%, 120%, 100%
(The first value of category A is 5. Therefore the line graph should display A's values relative to 5. It's values 5, 8, 8, 10 are then displayed as the mentioned percentages. The first value of category B is 10, so B's values should be displayed relative to 10).
With a date slicer set to filter years 2001-2003, I want the line values to become:
A: 100%, 100%, 125%
B: 100%, 150%, 125%
(Due to the slicer the first value of category A is 8, so I want the % values relative to 8. The first value of B is also 8)
I was thinking of writing a measure for this. Can anyone help me with it? Thank you in advance.
You can create a measure to establish the earliest filtered year, the value for that year, then divide each evaluated value by the min year value:
MyMeasure =
VAR MinYear =
CALCULATE (
MIN ( MyTable[Year] ),
ALLSELECTED ( MyTable[Year] )
)
VAR BaseValue =
CALCULATE (
SUM ( MyTable[Value] ),
REMOVEFILTERS ( MyTable[Year] ),
MyTable[Year] = MinYear
)
VAR CurrentValue =
SUM ( MyTable[Value] )
RETURN
DIVIDE (
CurrentValue,
BaseValue
)
Which results in:
Related
I would like to ask about some algorithms related to checking if a customer can book a table at the store?
I will describe my problem with the following example:
Restaurant:
User M has a restaurant R. R is open from 08:00 to 17:00.
Restaurant R has 3 tables (T1, T2, T3), each table will have 6 seats.
R offers F1 food, which can be eaten within 2 hours.
Booking:
R has a customer C has booked a table T1 for 5 people with F1 food | B[0]
B[0] has a start time: 9AM
M is the manager of the store, so M wants to know if the YYYY-MM-DD date has been ordered by the customer or not?
My current algorithm is:
I will create an array with the elements as the number of minutes of the day, and their default value is 0
24 * 60 = 1440
=> I have: arr[1440] = [0, 0, 0, ...]
Next I will get all the bookings for the day YYYY-MM-DD. The result will be an array B[].
Then I will loop the array B[]
for b in B[]
I then keep looping for the start_time, to the end_time of b with step of 1 min.
for time = start_time, time <= end_time. time++
With each iteration I will reassign the value of the array arr with index as the corresponding number of minutes in the day to 1
(It is quite similar to Sieve of Eratosthenes)
Then what I need to do is iterate over the array arr 1 more time, if there is at least 1 value 0 in the array it means YYYY-MM-DDdate is still bookable.
But my algorithm will not be optimal if increase the number of tables that the store has, the number of days to check is many days (for example from 2022-01-01 -> 2022-02-01), ...
Thank you very much.
P/S: Regarding the technology background, I am currently using laravel 9
I would appreciate any advises for my problem :
I have a list of stock with daily values (so several stocks and one value per day for each).
I'm trying to do a cumulative margin % on the total portfolio from the beginning of the year as a measure so i have the results on a daily basis.
So by example if the total portfolio value is 100 one day and 102 the day after and 104 the following day, i would like to have a measure with (for these 3 days) 0, 2, 4%.
I have a measure calculating the margin % of the whole portfolio per day (i can't have a column as the data is not portfolio but stock based) :
And what i would like to achieve is the following :
I tried to do a =CALCULATE(sum(dailies[marge_daily_percent_measure]); FILTER(all(dailies);INT(dailies[Date (Year)])=[annee]))
(the filter is to get the current year data) but the sum cannot be applied to the measure (he's looking for a column).
I also tried a TOTALYTD but i then have 2 issues : The Sum still cannot be applied to the measure and i also need the result on a daily basis.
Thanks for any hints.
Assuming your table with stock prices looks like this
Date
Value
30 December 2021
104
31 December 2021
106
03 January 2022
107
04 January 2022
107
05 January 2022
106
06 January 2022
95
07 January 2022
106
10 January 2022
110
I have calculated a Margin measure, DAX below. And cumulative measure using SUMX.
DAX: Margin
Margin =
VAR _SelectedDate =
SELECTEDVALUE ( 'Table'[Date] )
VAR _SelectedValue =
SELECTEDVALUE ( 'Table'[Value] )
VAR _PreviousDate =
CALCULATE ( MAX ( 'Table'[Date] ), 'Table'[Date] < _SelectedDate )
VAR _PreviousValue =
CALCULATE ( SUM ( 'Table'[Value] ), 'Table'[Date] = _PreviousDate )
VAR Margin =
DIVIDE ( _SelectedValue - _PreviousValue, _PreviousValue )
RETURN
Margin
DAX: Margin Cumulative
Cumulative Margin =
VAR _SelectedDate =
SELECTEDVALUE ( 'Table'[Date] )
VAR Cumulative =
CALCULATE (
SUMX ( VALUES ( 'Table'[Date] ), [Margin] ),
'Table'[Date] <= _SelectedDate
)
RETURN
Cumulative
Bear in mind that the final percentage value you get from Cumulative Margin is not the same as the difference from the first value against the last value. In this case, (110-104)/104 = 5.77%. With the Cumulative, I get 6.91%
Output
One way I've built cumulative measures in the past is to do the following logic to filter on date. Assuming you use this in some kind of time-sliced view (like your table, or a linechart), this should only grab the dates on/before 'todays' date for each row.
_Cumulative_ClosedTasks =
CALCULATE (
[_ClosedTasks],
FILTER (
ALL ('Date'[Date]),
'Date'[Date] <= MAX ('Date'[Date])
)
)
([_ClosedTasks] is just a basic SUM metric)
Does this approach work for your data?
I need to sum the values of column resulting from the table resulting from Summarize Funtion.
For e.g. my Data Set 'Tab' is like this
Type Value
A 10
A 10
A 10
B 20
B 20
B 20
C 30
C 30
C 30
The result from Summarize(Tab,[Type],AVG([Value])) will be like following
A 10
B 20
C 30
And the final result required from this result set is 10+20+30 i.e. 60.
Please help
You can use SUMX function.
Sum of Avg =
SUMX (
SUMMARIZE ( Tab, [Type], "Total Average", AVERAGE ( Tab[Value] ) ),
[Total Average]
)
It will give you the total if there is not any Type context affecting the measure:
Let me know if this helps.
You need to declare a name for it.
Total Value = Summarize(Tab,'Tab'[Type],"Total value",SUM('Tab'[Value])
I have a community matrix (samples x species of animals). I sampled the animals weekly over many years (in this example, three years). I want to figure out how sampling timing (start week and duration a.k.a. number of weeks) affects species richness. Here is an example data set:
Data <- data.frame(
Year = rep(c('1996', '1997', '1998'), each = 5),
Week = rep(c('1', '2', '3', '4', '5'), 3),
Species1 =sample(0:5, 15, replace=T),
Species2 =sample(0:5, 15, replace=T),
Species3 =sample(0:5, 15, replace=T)
)
The outcome that I want is something along the lines of:
Year StartWeek Duration(weeks) SpeciesRichness
1996 1 1 2
1996 1 2 3
1996 1 3 1
...
1998 5 1 1
I had tried doing this via a combination of rollapply and vegan's specnumber, but got a sample x species matrix instead of a vector of Species Richness. Weird.
For example, I thought that this should give me species richness for sampling windows of two weeks:
test<-rollapply(Data[3:5],width=2,specnumber,align="right")
Thank you for your help!
I figured it out by breaking up the task into two parts:
1. Summing up species abundances using rollapplyr, as implemented in a ddplyr mutate_each thingamabob
2. Calculating species richness using vegan.
I did this for each sampling duration window separately.
Here is the bare bones version (I just did this successively for each sampling duration that I wanted by changing the width argument):
weeksum2 <- function(x) {rollapply(x, width = 2, align = 'left', sum, fill=NA)}
sum2weeks<-Data%>%
arrange(Year, Week)%>%
group_by(Year)%>%
mutate_each(funs(weeksum2), -Year, -Week)
weeklyspecnumber2<-specnumber(sum2weeks[,3:ncol(sum2weeks)],
groups = interaction(sum2weeks$Week, sum2weeks$Year))
weeklyspecnumber2<-unlist(weeklyspecnumber2)
weeklyspecnumber2<-as.data.frame(weeklyspecnumber2)
weeklyspecnumber2$WeekYear<-as.factor(rownames(weeklyspecnumber2))
weeklyspecnumber2<-tidyr::separate(weeklyspecnumber2, WeekYear, into = c('Week', 'Year'), sep = '[.]')
I need a way to align tick marks on two separate axis, while being able to control the "step" value (value between tick marks), where both axis start at mark 0 and end on a different maximum value.
Why this problem:
Flot, the JS charting package has an option to align tick marks, but when I do, I cannot control the step value. I can however control the step value directly, but then I lose the ability to align tick marks. I can however revert to defining my own max and step values, to get what I need (aligned tick marks while maintaining desired step value), but I need some help. yielding this question (read on for details).
Example
Let a be maximum value on axis A and b, be maximum value on axis B.
In this example, let a = 30, and b = 82.
Let's say I want 6 tick marks (not counting the extra tick mark at end of axis). In reality I guessed at 6 after trying out a few.
Once I have a desired number of tick marks, I can do something like this:
30 / 6 = 5 (I just go the needed step value for axis A)
Now need to figure out tick alignment for axis B
82 / 6 = 13.67 (not a good value, I prefer something more rounded)
move max value of B to 90 , where 90 / 6 = 15 (good - I just got the needed step value for axis B)
End Result
Input:
a_max = 30, b_max = 82
(in reality a_max could be 28.5, 29.42, b_max could be 84, 85.345, etc)
Output:
a_adjusted_max = 30, b_adjusted_max = 90,
a_step = 5, b_step = 15
number of ticks = 6 (+1 if count the end)
Visual:
|---------|---------|---------|---------|---------|---------> A
0 5 10 15 20 25 30
|---------|---------|---------|---------|---------|---------> B
0 15 30 45 60 75 90
Summary of "Demands"
Need step value for each axis to be one of 1, 2, 5, 10, 15, 20, 25, 50, 100 (in example was 5 for A, 15 for B)
Need adjusted max value for each axis (in example was 30 for A, 90 for B)
Need number of ticks to match for both axis
(optional) Number of ticks is flexible but should be anywhere between 4 and 12 as a sweet spot
adjusted max value is at or greater than original max value, and is located at a "rounded number" (i.e. 90 is prefered over 82 as in my above example)
Problems (Question)
I need to remove most of the guessing and automate tick mark generation.
i.e. at first, I Need better way to get number of tick marks because I guessed at number of tick marks I wanted above, because I wanted a good "step" value, which can be something like 1, 2, 5, 10, 15, 20, 25, 50, 100. Max values start at 4, and can go up to 100. In rarer cases go up to 500. In most cases the max values stay between 30-90.
How can I do so?
Here's a procedure I came up with. I'm assuming you only want integers.
choose a number of ticks from 4 to 12
calculate the number of steps needed for the A and B axes using this number of ticks
find how much we would have to extend axis A and axis B using these step values; add these numbers together and remember the result
repeat from the start for the next tick value
we choose the number of ticks that gives the minimal score; if there is a tie we choose the smaller number of ticks
Here are some example results:
a=30, b=82 gives 4 ticks
0 10 20 30
0 28 56 84
a=8, b=5 gives 6 ticks
0 2 4 6 8 10
0 1 2 3 4 5
Here's the pseudocode:
a = range of A axis
b = range of B axis
tickList[] = {4,5,6,7,8,9,10,11,12}
// calculate the scores for each number of ticks
for i from 0 to length(tickList)-1
ticks = tickList[i]
// find the number of steps we would use for this number of ticks
Astep = ceiling(a/(ticks-1))
Bstep = ceiling(b/(ticks-1))
// how much we would need to extend the A axis
if (a%Astep != 0)
Aextend[i] = Astep - a%Astep
else
Aextend[i] = 0
end
// how much we would need to extend the B axis
if (b%Bstep != 0)
Bextend[i] = Bstep - b%Bstep
else
Bextend[i] = 0
end
// the score is the total extending we would need to do
score[i] = Aextend[i] + Bextend[i]
end
// find the number of ticks that minimizes the score
bestIdx = 0
bestScore = 1000;
for i from 0 to length(tickList);
if (score[i] < bestScore)
bestIdx = i
bestScore = score[i]
end
end
bestTick = tickList[bestIdx]
bestAstep = ceiling(a/(bestTick-1))
bestBstep = ceiling(b/(bestTick-1))
A axis goes from 0 by bestAstep to bestAstep*bestTick
B axis goes from 0 by bestBstep to bestBstep*bestTick