PowerPivot/DAX中实现Excel PERCENTRANK.INC函数的计算逻辑问询
解决DAX中模拟Excel PERCENTRANK.INC的问题
我之前在把Excel报表转PowerPivot的时候也踩过这个坑!DAX确实没有直接对应PERCENTRANK.INC的函数,但只要搞清楚Excel这个函数的底层计算逻辑,就能精准复刻出一致的结果。
先明确Excel PERCENTRANK.INC的计算逻辑
Excel的PERCENTRANK.INC核心是考虑重复值的中间位置,具体步骤是:
- 把目标数据集按升序排序,记总数据量为
n; - 对要计算的数值
x,统计两个关键值:L:数据集中严格小于x的数值个数;E:数据集中等于x的数值个数;
- 最终百分比排名的公式是:
(L + (E - 1)/2) / (n - 1)
举个例子验证:比如数据集[1,3,3,5],n=4:
- 对
x=3,L=1(只有1小于3),E=2(两个3),代入得(1 + (2-1)/2)/(4-1) = 1.5/3 = 0.5,和Excel直接计算的结果完全一致。
你的近似公式为什么有差异?
你用的公式是=(COUNT($A$2:$A$10)-B2)/(COUNT($A$2:$A$10)-1),其中B2=RANK.EQ(A2,$A$2:$A$10,0)——这里的问题在于:
RANK.EQ(...,0)是降序排名,转换后相当于用“大于等于x的数值个数”来推导,没有考虑重复值的中间位置;- 对于重复值,所有相同数值的RANK.EQ结果是一样的,直接代入会导致重复值的百分比排名偏高或偏低,和Excel原生结果产生偏差。
DAX实现Excel式的PERCENTRANK.INC
根据上面的逻辑,我们可以用DAX写一个自定义度量值(或者计算列)来精准模拟:
计算列版本(针对每行数据)
假设你的数据列是Table[Value],新建计算列:
PERCENTRANK_INC = VAR n = COUNTROWS(Table) VAR current_value = Table[Value] VAR L = CALCULATE(COUNTROWS(Table), Table[Value] < current_value) VAR E = CALCULATE(COUNTROWS(Table), Table[Value] = current_value) RETURN DIVIDE(L + (E - 1)/2, n - 1)
度量值版本(针对筛选上下文)
如果需要在度量值中使用(比如配合切片器等),可以调整为:
PERCENTRANK_INC_Measure = VAR selected_value = SELECTEDVALUE(Table[Value]) VAR n = COUNTROWS(ALLSELECTED(Table)) VAR L = CALCULATE(COUNTROWS(Table), ALLSELECTED(Table), Table[Value] < selected_value) VAR E = CALCULATE(COUNTROWS(Table), ALLSELECTED(Table), Table[Value] = selected_value) RETURN DIVIDE(L + (E - 1)/2, n - 1)
这个DAX公式完全遵循Excel的计算逻辑,计算结果会和PERCENTRANK.INC完全一致,你可以测试一下!
内容的提问来源于stack exchange,提问作者Chris




