文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

直方图是我最喜欢的图表类型之一,并且出于统计的原因,这可能是我最经常使用的图表。直方图由 Karl Pearson (数理统计之父) 在1800年代后期设计,它是简单的几何形状,稳健,并允许你看到数据的分布。

然而,如果你不理解是什么驱动了图表,它会让人困惑,这也许就是你不经常在一般的出版物中看到它的原因。

并不是柱状图

Bar chart vs histogram

最常见的误解之一是将直方图看作柱状图。这是可以理解的,因为他们看起来很类似。两者都使用并排放置的柱形状,而柱状的高度是主要的视觉提示, but the small differences between them change interpretation significantly.

第 1 段(可获 1.56 积分)

主要区别,显示在右侧图片中,在于柱状图显示类别数据(有时是序列数据),而直方图在横轴上显示连续变量。同时,柱状图中的视觉提示是柱形的高度,而直方图使用面积,例如,宽度乘以高度。

这意味着你以不同的方式理解两种图表类型。柱形图用于类别,而直方图用于分布。后者可以让你看到单一变量的扩展,而且它可能向左或向右倾斜,聚集在中间, 低峰值与高峰值等等。自然地,它随着数据集而变化。

第 2 段(可获 1.41 积分)

尽管柱形的宽度通常是相同的宽度。最后,直方图使用面积而不是高度来表示值,柱形的宽度会发生变化。这通常可以更好地看到长尾或是查看噪声更少的稠密区域。

主要注意点:柱状图与直方图是不同的。

现在让我们近距离来看一下在实践中这是如何工作的。

直方图销毁

出于保存的需要,我已经在该教程的下载中包含了数据文件。作为例子,我们将会看到经典的一个:人群的身高。更具体而言,是2013-2014赛季 NBA 篮球运动员的身高。可下载的数据格式位于 Best Tickets 文章 的结尾处。

第 3 段(可获 1.59 积分)

如果你还没有下载安装 R,那么现在正是下载安装的好时机。它是免费,开源的,如果你需要经常处理数据,它是非常值得学习的统计计算语言。 在这里下载

同时将工作目录设置为你保存该教程代码的任意位置。假定你已经打开 R 控制台,使用 read.csv() 载入 CSV 文件。

# Load the data.
players <- read.csv("nba-players.csv", stringsAsFactors=FALSE)

存在多个变量,包括年龄,工资以及体重,但是出于本教程的目的,你仅对身高感兴趣,也就是 Ht_inches 列。

第 4 段(可获 1.21 积分)

首先是柱状图。为所有的运动员生成柱状图并不合理,但是你可以仅为金州勇士队的运动员生成柱状图。

warriors <- subset(players, Team=="Warriors")
warriors.o <- warriors[order(warriors$Ht_inches),]
par(mar=c(5,10,5,5))
barplot(warriors.o$Ht_inches, names.arg=warriors.o$Name, horiz=TRUE, border=NA, las=1, main="Heights of Golden State Warriors")

你可以得到如下的柱状图:

01-Warriors heights

类似的,你可以为每个位置上的运动员的平均身高生成柱状图。

avgHeights <- aggregate(Ht_inches ~ POS, data=players, mean)
第 5 段(可获 0.69 积分)
avgHeights.o <- avgHeights[order(avgHeights$Ht_inches, decreasing=FALSE),]
barplot(avgHeights.o$Ht_inches, names.arg=avgHeights.o$POS, border=NA, las=1)

 

02-Average heights by position

在每一个柱状图中,为每一个运动员显示一个柱形,但是这占用大量的空间,而且受限于它所显示的信息量。第二个仅显示了聚合,而你丢失了人群中的差异。

让我们尝试不同的道路。假定你将运动员安排在身高区分的不同组中。每英寸有一个分组。也就是,如果某人的身高为78英寸,他就会进入其他人的身高也为78英寸的分组中。为每一英寸执行该操作,然后将分组以递增顺序排列。

第 6 段(可获 1.25 积分)

你可以使用图的形式很好地完成该操作。但是可以将运动员替换为点,每个点表示一个运动员。

htrange <- range(players$Ht_inches)  # 69 to 87 inches
cnts <- rep(0, 20)
y <- c()
for (i in1:length(players[,1])) {
     
    cntIndex <- players$Ht_inches[i] - htrange[1] + 1
    cnts[cntIndex] <- cnts[cntIndex] + 1
    y <- c(y, cnts[cntIndex])
 
}
plot(players$Ht_inches, y, type="n", main="Player heights", xlab="inches", ylab="count")
points(players$Ht_inches, y, pch=21, col=NA, bg="#999999")

你可以得到一张为你提供 NBA 运动员有多高的直观印象。大部分人位于75- 到 83-英寸范围,有一些人位于超高或相对较矮的范围。作为参考,美国人的 平均身高 为5英尺10英寸。

第 7 段(可获 0.94 积分)

03-Player dots

或者你可以将每个高度的点转换为柱形。

barplot(cnts, names.arg=69:88, main="Player heights", xlab="inches", ylab="count", border=NA, las=1)

 

注意,每个柱形表示特定高度的人数而不是运动员的实际身高,正如你在本教程开头所看到的那样。看起来似乎你自己得到了一个直方图。

04-Player heights as bars

生成直方图

你并不需要每次实际去数每个运动员。R 中有一个 hist() 函数可以为我们完成该操作。向该函数传递运动员身高作为第一个参数,这样我们就完成了。你可以修改群组或者在统计术语中将其称为箱子(bins)的尺寸。你可以以五英寸为间隔生成箱子,而不是每英寸生成箱子。例如,71到75英寸(包含)为一个箱子,而76到80英寸为另一个箱子。再次说明,你选择的间隔依赖于数据以及你希望看到的变化。

第 8 段(可获 1.91 积分)
par(mfrow=c(1,3), mar=c(3,3,3,3))
hist(players$Ht_inches, main="NBA Player Heights", xlab="inches", breaks=seq(65, 90, 1))
hist(players$Ht_inches, main="NBA Player Heights", xlab="inches", breaks=seq(65, 90, 2))
hist(players$Ht_inches, main="NBA Player Heights", xlab="inches", breaks=seq(65, 90, 5))

 

下面是相同的数据如何使用不同的方式进行显示。

05-Histograms with different bin size

如果你回忆一下,柱形的宽度并不必须是统一的。

par(mfrow=c(1,3), mar=c(3,3,3,3))
hist(players$Ht_inches, main="NBA Player Heights", xlab="inches", breaks=c(seq(65, 75, 2), 80, 90))
hist(players$Ht_inches, main="NBA Player Heights", xlab="inches", breaks=c(65, 75, seq(80, 90, 2)))
第 9 段(可获 0.31 积分)
hist(players$Ht_inches, main="NBA Player Heights", xlab="inches", breaks=c(65, seq(70, 80, 1), 90))

 

06-Varied width

我建议你小心该操作。其一,你也许会混淆一些数据,其二,你可能会模糊你数据中有趣的部分。不要害怕深度变化。

回到起始。

你了解了每个运动员的平均身高。那仅是一个表示某个位置的运动员人群的数字。所有位置的分布更为有趣。

par(mfrow=c(2,3), las=1, mar=c(5,5,4,1))
positions <- unique(players$POS)
for (i in1:length(positions)) {
第 10 段(可获 0.83 积分)
    currPlayers <- subset(players, POS==positions[i])
    hist(currPlayers$Ht_inches, main=positions[i], breaks=65:90, xlab="inches", border="#ffffff", col="#999999", lwd=0.4)
}

这为运动员身高提供了一个更为特定的视角。例如, 斜线以平均80英寸高为中心,但有一些略高,而有一些略低。

07-Compare histograms

这里是将直方图水平排列的 完成的图像 , 而这里是另一个 沿边缘反转的直方图。它也有助于将多个直方图按逻辑顺序排列以更好比较。注意水平方向上的统一尺度。默认情况下,水平轴橫跨数据集范围,但是你可以在 hist() 函数中指定 分割,从而可以在各方向保持一致。下面的代码同时添加了一条中线 (为分割)。

第 11 段(可获 1.36 积分)
par(mfrow=c(5,1), las=1, mar=c(5,5,4,1), xaxs="i", yaxs="i")
for (i in1:length(avgHeights.o$POS)) {
    currPlayers <- subset(players, POS==avgHeights.o$POS[i])
    htMedian <- median(currPlayers$Ht_inches)
    h <- hist(currPlayers$Ht_inches, main=avgHeights.o$POS[i], breaks=65:90, xlab="inches", border=NA, col="#999999", lwd=0.4)
    maxFreq <- max(h$counts)
    segments(h$breaks, rep(0, length(h$breaks)), h$breaks, maxFreq, col="white")
     
    # Median line
    lines(c(htMedian, htMedian), c(-1, maxFreq), col="purple", lwd=2)
}

下面的布局确实需要一些空间,但是当你探索你的数据集时,这会非常有用。

第 12 段(可获 0.21 积分)

08-Histograms sorted

结束

希望这篇小文章有助于你理解经典的统计可视化。 它需要一些时间来适应,特别是如果它们对于你是全新的,但是它们有助于你更了解你的数据,所以它是值得这些小小的麻烦的。 分布通常比聚合更为有趣。

第 13 段(可获 0.71 积分)

文章评论