一、背景
在有了一批数据之后,我们很难说出这些数据代表什么。这需要我们提出一些假设,并通过视觉化、总结、建模等方式来寻求这些问题的答案。
这里有一些试探、摸索的成分,目的是加深我们对数据的理解,发现数据内部潜在的信息。
不过在这个过程中,我们会比较关注变量之间的变异和共变。其中,最基础要了解的就是数据的分布。
为了观察这些,我们常做的事情有以下:
二、观察变异variance
2.1 视觉化变量分布情况
对于分类变量,我们常用条形图来显示。
对于连续变量,我们常用直方图来显示。
下面我们分别举例说明:
分类变量-条形图
(Categorical Variable-Barchart)
这里我们用到之前的数据集diamonds,我们想看到不同切割质量的钻石数量的分布。你就可以用到ggplot+geom_bar这个方式。不会的参照之前的文章
ggplot(data=diamonds)+geom_bar(mapping=aes(x=cut))
cut:
quality of the cut (Fair, Good, Very Good, Premium, Ideal)
纵坐标就展示了不同切割质量的钻石的数量。其中ideal的钻石最多。
连续变量-直方图
Continuous variable-Histogram
比如我们想知道钻石的大小的分布。
这里记录钻石大小的就是carat(克拉)这个变量
这是我们就用ggplot+geom_histogram这样的形式来。
ggplot(data=diamonds)+geom_histogram(mapping=aes(x=carat),binwidth=0.5)
binwidth就是下面的横坐标分段。
在直方图中,x轴以多大的单位切割,图像展现出来的样子还是不一样的。
所以,我们可以多尝试一下对这个范围进行调整。
比如,
diamonds %>% filter(carat<3) %>% ggplot()+geom_histogram(mapping=aes(x=carat),binwidth=0.1)
对比一下上图,是不是就有更多细节展现出来了。
你可以再细化一下:
diamonds %>% filter(carat<3) %>% ggplot()+geom_histogram(mapping=aes(x=carat),binwidth=0.01)
从这里我们看出,在整体的分布中,会有几个子分部。
直方图的叠加
当然,我们有时候想看的是不同的变量的分布。
可以用geom_freqpoly(),用法和geom_histogram()一样。
diamonds %>% filter(carat<3) %>% ggplot()+geom_freqpoly(mapping=aes(x=carat,color=cut),binwidth=0.1)
这样,我们就可以看到不同的切割程度的钻石,在不同克拉数这个维度上数量的变化。
这个时候,我们看到纵坐标是数值,这样,其实不太好看到分布的差异,因为整体的数量差别太大了。这个时候,我们需要看到密度图就好了。
我们想要看不同的价格、不同的切割质量的钻石都占比多少。那可以用下面的代码。
ggplot(data=diamonds)+geom_freqpoly(mapping=aes(x=price,y=after_stat(density),color=cut),binwidth=500)
这里加了一句代码y=after_stat(density),代表着把y轴的数据进行整理转化,整理成密度数据。
2.2 去除异常值
异常值有时是数据录入错误,有时却有着重大含义。
在直方图中,异常值有时是不方便观测的。比如说,在diamonds这个数据集中,变量y代表着钻石的维度之一。
如果我们采用之前的方法,可能就是以下代码:
ggplot(data=diamonds)+geom_histogram(mapping=aes(x=y),binwidth = 0.5)
瞅一瞅,纵坐标的范围是0-12000,这范围大到,有时我们看不到有没有一些异常值。所以我们用coord_cartesian这个函数来调整y坐标的范围。
ggplot(data=diamonds)+geom_histogram(mapping=aes(x=y),binwidth = 0.5)+coord_cartesian(ylim=c(0,50))
你瞧,y的范围被缩小到了0-50,这个时候,我们就看到y在30到60之间其实也是有一些值的。
接下来,我们就可以思考这些异常值代表着什么。
三、观察共变-covariance
之前的变异描述的是一个变量的变化,covariance描述的是变量之间的变化。也就是说,当一个变量变化的时候,其它的一个或多个变量也以某种方式一起变化。
研究共变最好的方式就是视觉化不同变量之间的关系。
但是到底怎么研究,这要取决于变量的类型。
3.1 分类变量-连续变量
比较好的描述分类变量分布的就是箱线图。
箱线图有几个特征值是我们需要了解的。
那我们想看看diamonds数据集中,不同切割品质的钻石都是什么价格。
ggplot(data=diamonds)+geom_boxplot(mapping=aes(x=cut,y=price))
这样我们就能大体知道不同切割品质的钻石,整体价位分布是怎样的了。
在这个例子中,品质从Fair------Ideal是有顺序的。如果面对没有顺序的分类,我们可能想要排排序,比如,我想要根据中位数大小排序,就可以下按下面这样写:
ggplot(data=diamonds)+geom_boxplot(mapping=aes(x=reorder(cut,price,median),y=price))
箱线图就有了顺序,惊讶地发现,品质最差的钻石,卖出去的价格,整体还是偏高的。
关于箱线图一些其他的操作,参照:
箱线图基础
3.2 分类变量-分类变量
统计两个分类变量时,想要看不同组合的数目,可以用geom_count函数。
如:
ggplot(data=diamonds)+geom_count(mapping=aes(x=cut,y=color))
还有一种方式,可以用dplyr种的count函数,它可以统计出不同组合的数量。
diamonds %>% count(color,cut)
为了视觉化,我们可以用geom_tile函数来呈现。
diamonds %>% count(color,cut)%>%ggplot()+geom_tile(mapping=aes(x=color,y=cut,fill=n))
3.3 连续变量-连续变量
一个非常好的探索两个连续变量之间关系的方式就是用散点图,这个之前我们在散点图基础中讲过。
例如:
ggplot(data=diamonds)+geom_point(mapping=aes(x=carat,y=price))
不过我们看到,因为diamonds数据集太多了,所以散点图出现了交叠的现象,尤其是左下角那黑黑的一块,确实影响对数据的分析。
我们之前学过一些方法就是用alpha属性。
比如:
ggplot(data=diamonds)+geom_point(mapping = aes(x=carat,y=price),alpha=1/100)
这样越浓的地方点越多。但是这样看还是比较抽象。
所以我们可以用geom_bin2d的方式。
geom_bin2d把坐标系分成2d的方块,然后展示出每个小方块里面有多少个点,可以算是geom_point的一个变式。
如下:
ggplot(data=diamonds)+geom_bin2d(mapping=aes(x=carat,y=price))
不过上面的图还是有些糊,一个措施是用geom_hex()来补救,这个函数就是让每一个单位变成一个有边界的六边形。但是要使用它,得先安装hexbin包。
install.packages("hexbin")
ggplot(data=diamonds)+geom_hex(mapping=aes(x=carat,y=price))
手动对连续变量进行分组
还有一种方式就是对连续变量进行分组,分组之后,我们就可以用之前的探索分类变量和连续变量的方法来探索两个连续变量。
ggplot(data=diamonds,mapping=aes(x=carat,y=price))+geom_boxplot(mapping=aes(group=cut_width(carat,0.1)))
在这里,用cut_width把x坐标分成不同的区块,再用group分组。除了cut_width进行分组外,也可以用cut_number来操作。
cut_width是按照宽度来分组,cut_number是分成多少组。
如下:
ggplot(data=diamonds,mapping=aes(x=carat,y=price))+geom_boxplot(mapping=aes(group=cut_number(carat,20)))