5.8 在Excel中绘制直方图
使用Microsoft Excel来绘制数据分布,可以让你对统计数据有一个更好的理解。
俗话说“一图胜千言。”这有一定的道理。一幅图往往是理解1000个数字的最好方式。人是视觉导向的。我们善于看一张图片并观察不同的特征,不善于看有1000个数字的列表。
直方图是帮助我们理解数据的一种最有力的工具,它是关于值分布的图。下面是直方图的概念。假设你有很多数据,比方说,1955年至2004年间,所有6032名每场比赛中安打数为3.1及以上的棒球选手的安打率7。我们同时假定,你想知道这些值是如何分布的。最低值是多少,最高值是多少?低的值是否比高的值更多?安打率是完全介于0~0.400的随机数,还是存在某种模式?
7在棒球运动中,安打表示击球手把投手投出来的球击出到界內,使打者本身能至少安全上到一垒的情形。——译者注
安打率可以有许多不同的值。1955年到2004年,6032名球员有合格的安打率,有1229个独特的值。您可以绘制每个独特安打率下的球员数(虽然我无法想象这个图是什么样子)。但我们并不真正关心每一个独特的值,例如,13名球员有0.2 862的安打率不是那么有趣。相反,我们可能会想知道有非常相似安打率的球员数量,比如说安打率在0.285~0.290的球员数量是多少。
让我们把每个范围想象成一个桶。每个赛季球员进入一个桶里。例如,1959年,汉克·亚纶(Hank Aaron)有0.354的安打率,所以我们会把这个赛季放在0.350~0.355的桶里。所以,下面是我们的方案:我们把每个赛季球员放到一个桶里,计算每个桶里赛季球员的数量,并绘制图形展示(按升序排列)每个桶里球员的数量。这个图就是直方图。
5.8.1 代码
在这个例子中,我想看看安打率的分布。我用了包含每个球员每年总的安打统计的表格(以及每个球员所在的球队名单),还有我称为b_and_t的表格。我只选择了1955年至2004年间,获得足够打席数够格成为联赛冠军的球员:
SELECT b.playerID , M.nameLast , M.nameFirst , b.yearID , b.teamG ,
b.teamIDs , b.AB , b.H ,
b.H / b.AB AS AVG ,
b.AB + b.BB + b.HBP + b.SF as PA
FROM b_and_t inner join Master M
on b.playerID = m.playerID
WHERE yearID > 1954
AND b.AB + b.BB + b.HBP + b.SF > b.teamG * 3.1 ;
运行此查询后,我把结果保存为Excel文件,名为batting_averages.xls。
在Excel中绘制直方图的一种方法是使用分析工具库(Analysis ToolPak)的加载项。你可以从Tools菜单通过选择Add…Ins来添加,然后选择分析工具库(Analysis ToolPak)。这给Tools菜单增加了一个新的菜单项,叫数据分析。它引入了一些新功能,包括直方图这个功能。但我觉得这个界面混乱而且缺乏灵活性,所以我用了别的方法。
下面是我创建直方图的方法。
1.在工作表的数据中,创建一个新的名为Range的列。
2.在本列的第一个单元格,对你希望为其绘制分布的值使用函数进行四舍五入。做到这一点最简单的方法来是使用ROUND函数的有效数字选项。在我的工作表中,列I包含了我想计算分布的值(安打率),所以我可以用一个公式,比如ROUND(I2,2)来四舍五入到最接近0.010。就个人而言,我发现0.005大小的桶更具描述性,所以我用了一个技巧。你可以在ROUND函数里乘以一个值,然后在函数外除以一个值,这样可以得到几乎任何大小的桶。在ROUND函数里,我乘以桶大小的倒数——这种情况下,是1/0.005=200。函数外面,我乘以桶的大小。在我的工作表中,列I包含了平均值。于是,我用ROUND(I2*200,0)/200作为我的公式。将此公式复制粘贴到工作表中的每一行。(你可通过双击单元格的右下角,快速快做到这一点。)
3.现在,我们已经准备好计算每个桶中玩家的数量了。选择工作表的所有数据,包括新的Range列。从Data菜单中选择数据透视表和数据透视图表报告。选择数据透视图报表,然后单击Finish(我们将使用所有的默认值)。我们将为我们的数据透视表选择两个区域。从数据透视表字段列表面板中,选择Range。将这个拖放到数据透视表的Drop Row Fields Here部分。接下来,拖放“playerID”到数据透视表的Drop Data Item Here部分。默认情况下,Excel将计算匹配每个范围值的球员ID数。数据透视表现在显示了每个桶中的项目数。你应该看到一张(非常难看关于)的每个桶中球员数量的图。
4.清理美化图表。(我喜欢擦除背景填充和线条,改变列宽。)图5-5的例子即为一张清理干净后的图表。

图5-5:数据透视图报表的直方图
通过直方图,我们看到,分布类似于一个钟形曲线,它向右侧倾斜,中心大约在0.275左右。
5.8.2 解读Hack
用公式计算组条的好处之一是,你能很容易地改变组条的公式。以下是采用其他公式时的几点建议:
ROUNDDOWN (<value> , <significance> )和ROUNDUP (<value> , <significance> )
这个ROUNDDOWN函数向下舍入到最近的有效数字。例如,ROUNDDOWN(3.59,0)等于3,ROUNDDOWN(3.59,1)等于3.5。同样,ROUNDUP是向上舍入到最近的有效数字。ROUNDUP(3.59,0)等于4,ROUNDUP(3.59,1)等于3.6。
LOG (<value> , <base> )
使用对数大小的组条时,有时可用此函数绘制对数刻度值。您可以结合LOG函数和ROUND函数来创建可变大小的组条。
CONCATENATE(…)
CONCATENATE函数不计算数字,它把文字放在一起。如果你想明确列出范围(如3.500~3.599),可以使用CONCATENATE来创建。例如CONCATENATE(ROUNDDOWN(3.59,1),"to",ROUNDUP(3.59,1)-0.01)返回3.5到3.59。
如果你想更进一步,可以用一个命名值取代组条。(例如,命名单元格A1 bin_size)。这可以很容易地动态改变组条大小和试验不同数量的组条。
——约瑟夫·阿德勒
