https://zhuanlan.zhihu.com/p/79522456
对于PowerBI使用者而言,经常碰到的一个问题是,想把度量值放到坐标轴上,却发现无法实现。尤其是初学者,更是习惯性的想这么做。
PowerBI星球嘉宾天行,摸索出了一个解决该问题的思路,请慢慢品读吧。
解决度量值不能作为坐标轴字段的问题
作者:天行
初入Power BI的门,很快就会被度量值和计算列的动态性吸引,进而义无反顾地跳进DAX的火坑中,然后……(省略号的内容留给曾经在坑中和正在坑中徘徊的各位自行填写吧 )
如何将度量值作为图表的轴,这是使用Power BI解决实际问题时绕不过去的“坑”之一,而这个问题常常是由对某类数据进行分类,然后需要对分类的情况进行统计时产生的。
正好星球中的米妮黄同学在群中提到一个关于课程学习动态评价的问题,本文就借与她探讨解决问题的示例,来一次性说清楚解决度量值作为图表轴的字段思路原理,方便大家举一反三,解决工作中类似的实际问题。
一、示例描述
基本情况:一批人参加多门课程学习,评价是否通过的标准为学习课程的门数。
解决要求:评价标准是动态的,根据动态评价标准(学习课程门数)评价每个人的学习状态,并实时统计这一批人中不同学习状态的人数。
建一个示例基础数据表【data】
需求具体化:该表中有11人,通过课程从7门到24门不等,根据动态评价标准,实时统计通过和未通过的人数。
二、解决思路
(1)通过新增计算列的方式解决
1、在【data】表中新增计算列【评价结果 计算列】
即设定通过标准为13,有8人显示“完成学习”,3人显示“继续努力”
2、增加一个度量值【人数累计 评价标准 计算列】统计不同状态的人数
人数 累计 评价标准 计算列 = COUNTROWS('data')
3、添加一个堆积柱形图,将【评价结果计算列】作为轴,【人数 累计 评价标准 计算列】作为值,可以呈现“完成学习”和“继续努力”的分类人数统计。
4、试图解决动态评价问题:通过【新建参数】功能设定一个动态评价标准。
如上操作后,将自动生成【通过标准】参数表和一个滑杆控件,其中【通过标准】表包含【通过标准】字段和【通过标准 值】度量值。
5、修改【评价标准计算列】公式为
评价结果 计算列 =
IF([通过课程]>=[通过标准 值],"完成学习","继续努力")
理论上应该可以根据动态调整的评价标准,对每个人进行重新评价。
结果发现尽管滑杆调整后,【通过标准 值】随之会发生正确变化,但是【评价结果 计算列】的结果始终不变,进一步研究会发现【评价结果 计算列】的判断标准居然一直是10,好诡异!
至此,通过计算列解决动态评价的问题已宣告失败,具体原因后面再分析。
(2)通过度量值的方式解决
1、新增【评价标准度量值】,与参数度量值绑定进行是否通过判断。
评价标准 度量值 =
VAR vMax=MAX('data'[通过课程])
Return
IF(vMax>=[通过标准 值],"完成学习","继续努力")
2、新增堆积柱形图,却发现【评价标准度量值】无法拖放进“轴”里,似乎又进入了死胡同。
下面进入本文的重点,如何解决度量值不能用作图表轴的问题?
01 | 新建一个过渡表【标准】
02 | 新建三个度量值
03 | 将【标准】表中的【标准】字段拖入堆积柱形图的"轴"中,将【数量选择】度量值放入堆积柱形图的”值“中,可以呈现分类统计人数结果。
04 | 再试着拖动滑杆动态调整评价标准,可以看到每个人的评价结果随之变化,堆积柱形图正确呈现每种分类人数的动态变化。
至此,我们另辟蹊径解决了度量值不能用作图表轴的问题。
![](https://pic2.zhimg.com/v2-6f8d796e0487e84e8f47410314d807f9_b.jpg)
三、原理探讨
在解决这个“小“问题的过程中,实际上涉及到DAX的两个核心问题:计算列的刷新原理和图表的本质,下面我们结合这个示例来深入探究。
(一)计算列为什么不能根据动态参数进行刷新?
在DAX的设计中,计算列是在数据装载的过程中进行计算刷新,可以简单理解为在点击【主页】菜单的【刷新】项时,对所有表的数据进行重新装载,或者重新打开Power BI文件时,计算列才会进行计算,其他时候计算列不会发生变化。
而度量值则是在计算上下文发生改变时,就会实时进行重新计算。
所以,在本例中,动态参数发生改变时,因为【data】表中每个人的学习课程数没有变化,所以【data】表中的计算列也不会重新计算。
进一步思考可以得出:计算列的原理是数据装载时一次性计算,主要占用内存资源;度量值是随着计算上下文的变化实时计算,主要占用CPU资源。
再往深处推演:如果同样的计算结果,表格中的行数越多,添加的计算列占用的内存将越多,同时报表打开的速度也会因为大量的计算列计算而随之减慢。
最后可以收获一条实际工作中的DAX使用原则:明细数据较多时,为保证报表打开效率,尽量使用度量值,而不要使用计算列;如果需要实时调整参数,实时得出分析结果,则只能使用度量值。
(二)图表的轴到底是什么?为什么度量值不能用作轴?
要理解图表的轴是什么,首先要理解图表是什么。
这一点可以通过PowerBI里面的实际操作来得出结论。
选择堆积柱形图,进行复制(Ctrl+C)、粘贴(Ctrl+V)操作,得到一个一模一样的堆积柱形图复制品,选中“复制品“,在【可视化】面板中切换为【表】,发现”复制品“转换成了一个普通的二维表。
从这个转换中,我们可以得出结论:PowerBI的图表本质就是表格(如果有兴趣,可以将每种图表都转换一次,看看结果是否一致),图表只是表格的一种表现形式。
那么为什么度量值不能当作轴呢?这个问题的答案同样可以通过实际操作推演出来。
新建一个表格,按照开始的思路,把【评价标准 度量值】和【人数 累计 评价标准 计算列】放到“值“中,得出两个风马牛不相及的结果:
【评价标准 度量值】是根据没有【姓名】筛选的情况下所有人课程的合计数去判断是否通过,结果自然是"完成学习".
【人数 累计 评价标准 计算列】是没有筛选上下文的的行计数,所以结果是11。
这两个结果虽然能够放到一个表格里面,但毫无实际意义,而图表是要呈现一种数据之间逻辑关系的结果,没有逻辑关系的度量值当然不能放到图表的轴里了。
那么这个堆积柱形图的意义应该是什么呢?
我们从“复制品”转换成功的表格中可以看到清晰的数据之间的逻辑关系:根据评价标准对数据进行分组聚合运算,得出每种标准的实际人数。
由此,我们已经推演出图表的核心原理:
1、图表的本质是表格
2、由于图表必须呈现数据间逻辑关系的意义,所以必须根据确定的标准(维度)对数据进行分组,然后进行各种聚合运算,这也就是为什么度量值不能作为图表的轴的根本原因。
既然已经明了图表的原理,具体解决办法就是雕虫小技了。
1、建立一个过渡表,对应每一种可能分类的类型;
2、用过渡表的分类标准字段作为图表中的轴字段(分组条件)
3、针对每种分类构建一个单独计数的度量值(【数量继续努力】和【数量 完成学习】)
4、构建【数量选择】度量值,通过判断筛选上下文的分类标准,调用对应的单独计数度量值,作为图表的值字段
这是一个解决DAX动态性的小套路,熟练掌握,灵活运用后可以解决很多具体问题。
您掌握了吗?
后记:
关于度量值不能作为图表轴字段的问题,曾经被当作PowerBI易用性远不如Tableau的证据,但是如果在理解了本文的推演原理,掌握了解决问题的套路之后,再回头看待这个所谓的“证据”,应该是PowerBI在易用性和灵活性之间的当前取舍,所谓度量值可以当轴字段的功能不过是一个过渡表小套路自动化的过程,从最近PowerBI的演进速度和方向来看,也许就在某次月度更新中就会不经意来到我们手边,让我们共同期待吧。