I would like to create a TopCount over multiple dimensions, and include a "rest"/"remainder" and a sub-total.
I use the following MDX on the default Sales schema in icCube:
with
member [Product].[Product].[All Products].[rest] as "All Products - top 2"
SET [top] AS
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) + s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
select
[Measures].[Amount] on 0
[top] on rows
from sales
The result is in the following picture.
How to get a value for "rest"? Using the formula: "All Products" -/- the Top 2
The answer will depend on whether the dimension includes many-to-many relations or not.
If there are no many-to-many, you can either use the SubCubeComplement function:
MEMBER [Product].[Product].[All Products].[rest] as Eval( SubCubeComplement( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]) ) , [Product].[Product].defaultMember )
or calculate it (all minus the sum of the TopCount set):
MEMBER [Product].[Product].[All Products].[rest] as ([Product].[Product].defaultMember) - Sum( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].currentMember )
The risk here is that in case you have many-to-many relations, the two solutions above can be subtracting unwanted rows (as they may contain articles that should have been in the final set.)
Therefore, if you have many-to-many relations use the Eval function with the following syntax:
MEMBER [Product].[Product].[All Products].[rest] as Eval( [Product].[Product].[Article].Members - TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].defaultMember )
The statement will therefore be (please note the adjustment on the [top] set definition):
with
// v1 (no many-to-many) - behaves like a FILTERBY
// MEMBER [Product].[Product].[All Products].[rest] as Eval( SubCubeComplement( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]) ) , [Product].[Product].defaultMember )
//v2 (no many-to-many)
// MEMBER [Product].[Product].[All Products].[rest] as ([Product].[Product].defaultMember) - Sum( TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].currentMember )
//v3 (many-to-many)
MEMBER [Product].[Product].[All Products].[rest] as Eval( [Product].[Product].[Article].Members - TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount]), [Product].[Product].defaultMember )
SET [top] AS
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
s1.CurrentMember * TopCount( [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) + s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
select
[Measures].[Amount] on 0
[top] on rows
from sales
Version 3 will also work if there are no many-to-many relations.
After some time puzzling I found the solution.
The solution is a combination of icCube's MDX++ functions, namely SubCubeMinus in combination with the category member.
Here's the answer:
with
SET [top 2] as
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) )
category calculated member [Product].[Product].[All Products].[rest] as subcubeminus(([Customers].[Geography].[All Regions] , [Time].[Calendar].[2010], [Product].[Product].[All Products]) , [top 2])
SET [top 2] as
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) )
SET [tuples_top2_rest_total] AS
Generate( { {[Customers].[Geography].[Region] } * [Time].[Calendar].[2010] } as s1,
TopCount( s1.CurrentMember * [Product].[Product].[Article].Members, 2, [Measures].[Amount] ) + s1.CurrentMember * {[Product].[Product].[All Products].[rest] , [Product].[Product].[All Products]} )
select
[Measures].[Amount] on 0
[tuples_top2_rest_total] on rows
from sales
Result
Explanation
Create the Top 2 using the Generate function;
Create the calculated category member "rest" (ie others) all the data in the cube for Total Region, 2010 and Total Product MINUS the TOP 2 per combination for region and 2010.
In a column I have values like 0.7,0.85, 0.45, etc but also it might happen to have 2.13 which is different than the majority of the values. How can I spotted this "outliers"?
Thank you
Call scipy.stats.zscore(a) with a as a DataFrame to get a NumPy array containing the z-score of each value in a. Call numpy.abs(x) with x as the previous result to convert each element in x to its absolute value. Use the syntax (array < 3).all(axis=1) with array as the previous result to create a boolean array. Filter the original DataFrame with this result.
z_scores = stats.zscore(df)
abs_z_scores = np.abs(z_scores)
filtered_entries = (abs_z_scores < 3).all(axis=1)
new_df = df[filtered_entries]
You could get the standard deviation and mean of the set and remove anything more than X (say 2) standard deviations from the mean?
The following would calculate the standard deviation
public static double StdDev(this IEnumerable<double> values)
{
double ret = 0;
if (values.Count() > 1)
{
double avg = values.Average();
double sum = values.Sum(d => Math.Pow(d - avg, 2));
ret = Math.Sqrt((sum) / (values.Count() - 1));
}
return ret;
}
In the following Kotlin code example I expected the value of parameter i to be equal to 0, such as is the case for the parameter k. The IDE reports all i, j and k as Int. Is it a bug or do I need to readjust my understanding of Kotlin casting inside expressions? For example, is there a rule to always promote/cast to Double inside expressions involving division, but not multiplication?
fun main() {
//Kotlin 1.3.61
val x = 100 * 1.0/100 //Double
val i = 100 * 1/100 //Int
val j = 1/100 //Int
val k = 100 * j //Int
println(x) //1.0
println(i) //1
println(j) //0
println(k) //0
}
I expected the value of parameter i to be equal to 0
The output is arithmetically right: 100 * 1 / 100 = (100 * 1) / 100 = 100 / 100 = 1 / 1 = 1
, such as is the case for the parameter k.
The value j is 0, so anything multiplied by it will be zero, as in case of k.
is there a rule to always promote/cast to Double inside expressions
involving division, but not multiplication?
If you divide integers, you will get an integer back. If one of the numbers is a Double, the result will be a Double:
val x = 100 * 1.0/100 //Double because 1.0 is a Double
--
There is actually already a discussion on kotlin forum to your problem here:
Mathematically speaking the current behaviour is correct.
This is called integer devision and results in the quotient as an
answer
I'm trying to re-implement the rma function from TradingView pinescript but I cannot make it output the same result as the original function.
Here is the code I developed, the code is basically the ema function, but it differs greatly from the rma function plot result when charting:
//#version=3
study(title = "test", overlay=true)
rolling_moving_average(data, length) =>
alpha = 2 / (length + 1)
sum = 0.0
for index = length to 0
if sum == 0.0
sum := data[index]
else
sum := alpha * data[index] + (1 - alpha) * sum
atr2 = rolling_moving_average(close, 5)
plot(atr2, title="EMAUP2", color=blue)
atr = rma(close, 5)
plot(atr, title="EMAUP", color=red)
So my question is how is the rma function works internally so I can implement a clone of it?
PS. Here is the link to the documentation https://www.tradingview.com/study-script-reference/#fun_rma It does show a possible implementation, but it does not work when running it.
Below is the correct implementation:
plot(rma(close, 15))
// same on pine, but much less efficient
pine_rma(x, y) =>
alpha = 1/y
sum = 0.0
sum := alpha * x + (1 - alpha) * nz(sum[1])
plot(pine_rma(close, 15))
There is a mistake in the code on TradingView, the alpha should be 1/y not y. This Wikipedia page has the correct formula for RMA
Wikipedia - moving averages
I have a Situation where I am looking for MDX Guidance.
Environment: SQL Server 2008 R2,SSRS 2008 R2
Dimension:Columns
DimMainProvider :ProviderName
DimAcademicYear:AcademicYear
DimSectorSubjectArea:Estyn
DimLearningAim:LearningAimReference
Fact:Columns
Learnings:MainProviderKey,AgeBandKey,LearningAimKey,SuccessFlag
What I want is
1) For a particular MainProvider Get Top 10 LearningAims by Success Rate and show it in tablix
2) For a each Row on tablix also show Box plot graph which essentially needs Min,Max,Quartile1,Quartile3 success rates of that particular LearningAim across all Mainproviders
What I have is 2 MDX queries
a) one which gets top 10 Activities for a Main Provider (Simplified
Version of MDX below)
WITH
SET Top10LearningAimsForSuccessRate
AS
NonEmpty(
TOPCOUNT([ReportedLearningAims],10,[Measures].[SuccessRate]),
[Measures].[SuccessRate]
)
SELECT
{
[Measures].[SuccessRate]
} ON COLUMNS
,NON EMPTY
{
EXISTS(
Top10LearningAimsForSuccessRate
,,"Learnings")
} ON ROWS
FROM
(
SELECT {[Measures].[TerminatedAssessableLASum]
,[Measures].[SuccessfulLASum]} ON COLUMNS
,{(StrToSet("[DimMainProvider].[ProviderName].&[44]",CONSTRAINED))} On ROWS
FROM [FECube]
)
WHERE
( StrToSet("[DimAcademicYear].[AcademicYear].[AcademicYear].[2009/10]",CONSTRAINED),
StrToSet("[DimSectorSubjectArea].[Estyn].&[2]",CONSTRAINED)
)
b) Another query which accepts LearningAim as a Parameter and does
Statistical Calculations and gives me values (Simplified Version of
MDX below)
WITH
SET ProviderwideLearningAims
AS
ORDER(
NonEmpty( [DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]
)
,[Measures].[SuccessRate],BASC
)
MEMBER [Measures].[MaxValue]
AS
Max(ProviderwideLearningAims,[SuccessRate]),FORMAT_STRING = "Percent"
MEMBER [Measures].[MinValue]
AS
Min(ProviderwideLearningAims,[SuccessRate]),FORMAT_STRING = "Percent"
MEMBER [Measures].[MedianValue]
AS
Median(ProviderwideLearningAims,[SuccessRate]),FORMAT_STRING = "Percent"
Member [Measures].[ProviderCount] As [ProviderwideLearningAims].Count
MEMBER [Measures].[MeanValue]
AS
(SUM(ProviderwideLearningAims,[SuccessRate])/[Measures].[ProviderCount]),FORMAT_STRING = "Percent"
MEMBER [Measures].[LearningAimUniqueName]
AS
[DimLearningAim].[LearningAimReference].CurrentMember.UniqueName
Select
{ [Measures].[LearningAimUniqueName]
,[Measures].[MinValue]
,[Measures].[MaxValue]
,[Measures].[MedianValue]
,[Measures].[MeanValue]
} ON COLUMNS,
{
NonEmpty([DimLearningAim].[LearningAimReference].[LearningAimReference],ProviderwideLearningAims)
} ON ROWS
FROM
(
SELECT
StrToSet("[DimLearningAim].[LearningAimReference].&[50024991]",CONSTRAINED) ON COLUMNS
FROM [FECube]
)
WHERE
( StrToSet("[DimAcademicYear].[AcademicYear].[AcademicYear].[2009/10]",CONSTRAINED),
StrToSet("[DimSectorSubjectArea].[Estyn].&[2]",CONSTRAINED)
)
My original Idea is to fire 2nd query for each Learning Aim received
from 1st query,but I am not able to implement this in SSRS Dataset
Model.
So Now I am back at MDX level and want somehow to merge these
two.
Here is how I fixed it with help from Deepak Puri on MSDN forums
With Set [Top10LearningAims] as TOPCOUNT(
Filter(([ReportedLearningAims]*[DimMainProvider].[ProviderName].MEMBERS),[DimMainProvider].[ProviderName].CURRENTMEMBER
IS STRTOMEMBER("[DimMainProvider].[ProviderName].&[44]") )
,10,[Measures].[TerminatedAssessableLASum]
)
MEMBER [Measures].[MaxValue] AS
Max(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]),FORMAT_STRING =
"Percent" MEMBER [Measures].[MinValue] AS
Min(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]),FORMAT_STRING =
"Percent" MEMBER [Measures].[MedianValue] AS
Median(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]), FORMAT_STRING =
"Percent"
MEMBER [Measures].[MeanValue] AS
Avg(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate]), FORMAT_STRING =
"Percent"
Member [Measures].[ProviderCount] as
Count(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate])) Member [Measures].[PercentileInt25] as
Int((([Measures].[ProviderCount] - 1) * 25) / 100) Member
[Measures].[PercentileFrac25] as (([Measures].[ProviderCount] - 1) *
25) / 100
- [Measures].[PercentileInt25] Member [Measures].[PercentileLo25] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt25]).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[PercentileHi25] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt25] + 1).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[Percentile25Value] as
([Measures].[PercentileLo25] * (1 - [Measures].[PercentileFrac25]))
+ ([Measures].[PercentileHi25] * [Measures].[PercentileFrac25]),
FORMAT_STRING = "Percent" Member [Measures].[PercentileInt75] as
Int((([Measures].[ProviderCount] - 1) * 75) / 100) Member
[Measures].[PercentileFrac75] as (([Measures].[ProviderCount] - 1) *
75) / 100
- [Measures].[PercentileInt75] Member [Measures].[PercentileLo75] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt75]).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[PercentileHi75] as
([Measures].[SuccessRate],
Order(NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]), [Measures].[SuccessRate],
BASC).Item([Measures].[PercentileInt75] + 1).Item(0)), FORMAT_STRING =
"Percent" Member [Measures].[Percentile75Value] as
([Measures].[PercentileLo75] * (1 - [Measures].[PercentileFrac75]))
+ ([Measures].[PercentileHi75] * [Measures].[PercentileFrac75]),
FORMAT_STRING = "Percent"
select { [Measures].[TerminatedAssessableLASum]
,[Measures].[SuccessfulLASum]
,[Measures].[SuccessRate]
,[Measures].[SectorTerminatedAssessableLASum]
,[Measures].[SectorSuccessfulLASum]
,[Measures].[SectorSuccessRate]
,[Measures].[ProviderCount] ,[Measures].[MinValue]
,[Measures].[MaxValue] ,[Measures].[MeanValue]
,[Measures].[Percentile25Value] ,[Measures].[MedianValue]
,[Measures].[Percentile75Value]} on COLUMNS,
EXISTS(NonEmpty(([DimLearningAim].[LearningAimReference].[LearningAimReference],[DimLearningAim].[LearningAimTitle].[LearningAimTitle]),([Top10LearningAims],[Measures].[SuccessRate]))*NonEmpty([DimMainProvider].[ProviderName].[ProviderName],
[Measures].[SuccessRate]),,"Learnings") DIMENSION PROPERTIES
MEMBER_CAPTION,MEMBER_UNIQUE_NAME ON ROWS from FECube WHERE
( StrToSet("[DimAcademicYear].[AcademicYear].[AcademicYear].[2009/10]",CONSTRAINED),
StrToSet("[DimLearnerAgeBand].[AgeBand].[All]",CONSTRAINED),
StrToSet("[DimLearningCourseLength].[CourseLength].[All]",CONSTRAINED),
StrToSet("[DimLearnerEthnicity].[Ethnicity].[All]",CONSTRAINED),
StrToSet("[DimLearnerGender].[Gender].[All]",CONSTRAINED),
StrToSet("[DimDeprivationDecile].[Decile].[All]",CONSTRAINED),
StrToSet("[DimSectorSubjectArea].[Estyn].&[2]",CONSTRAINED),
StrToSet("[DimLearningActivityLevel].[ActivityLevel].[All]",CONSTRAINED),
StrToSet("[DimLearningActivityType].[ActivityType].[All]",CONSTRAINED)
) CELL PROPERTIES VALUE ,BACK_COLOR ,FORE_COLOR ,FORMATTED_VALUE
,FORMAT_STRING ,FONT_NAME ,FONT_SIZE ,FONT_FLAGS