给女朋友写的生统资料_Part7
到目前为止,我们已经讲完了如何读取数据,如何提取数据、如何整理数据,在这一部分,我们来讲讲如何对生统的数据有一个大致的描述。
这一部分参考了《R语言实战》的7.1部分
用数据的方式呈现
一般来说,常见的数据描述方式包括均值,方差,中位数,最大值,最小值等等。R 里面都有对应的函数来检验,比如 mean
,var
等等。但为了快速地了解我们手头的数据,我们就可以用 summary
和 str
这两个函数。
我们以 test2 的数据集为例。
# 读取
test2 <- read.table("rawdata/test2.txt",header = T)
# head也是个查看数据的方式
> head(test2)
control low middle high
1 20.79 22.22 28.56 31.93
2 22.91 24.74 28.67 37.94
3 27.21 21.53 25.28 39.76
4 19.34 19.66 30.28 27.94
5 17.85 25.89 23.13 29.65
6 23.79 29.10 23.47 34.23
# 使用Summary
> summary(test2)
control low middle high
Min. :17.22 Min. :18.64 Min. :22.29 Min. :24.07
1st Qu.:19.35 1st Qu.:20.39 1st Qu.:25.05 1st Qu.:29.21
Median :22.60 Median :22.69 Median :28.67 Median :32.63
Mean :21.98 Mean :23.23 Mean :28.13 Mean :32.84
3rd Qu.:23.96 3rd Qu.:25.69 3rd Qu.:29.95 3rd Qu.:36.14
Max. :27.21 Max. :29.67 Max. :35.12 Max. :39.76
# 使用str
> str(test2)
'data.frame': 15 obs. of 4 variables:
$ control: num 20.8 22.9 27.2 19.3 17.9 ...
$ low : num 22.2 24.7 21.5 19.7 25.9 ...
$ middle : num 28.6 28.7 25.3 30.3 23.1 ...
$ high : num 31.9 37.9 39.8 27.9 29.6 ...
可以看到,summary 和 str 都是对每列的数据进行了描述。summary 偏向于描述数据的统计属性,比如最小值,最大值等等。str 偏向于描述数据的结构,比如我们可以看到数据总共是 15 行,4列。每列的数据都是数值型的数据。
让我们再来看看 test1 的数据集
> test1 <- read.table("rawdata/test1.txt",header = T)
> summary(test1)
yield seed
Min. :348 Min. :1.000
1st Qu.:362 1st Qu.:1.000
Median :376 Median :2.000
Mean :378 Mean :1.931
3rd Qu.:394 3rd Qu.:3.000
Max. :414 Max. :3.000
> str(test1)
'data.frame': 29 obs. of 2 variables:
$ yield: int 383 406 351 400 390 361 394 395 414 382 ...
$ seed : int 1 1 1 1 1 1 1 1 1 1 ...
当我们在用 Summary 和 str 看 test1 的数据集的时候,是不是感觉有那么一丝不太对。seed 那列的数据描述跟我们想的不太一样啊。事实上,还是因为没有把 seed 的那列变成因子型的变量导致的。让我们再次来做个转换。
> test1$seed <- factor(test1$seed)
> summary(test1)
yield seed
Min. :348 1:10
1st Qu.:362 2:11
Median :376 3: 8
Mean :378
3rd Qu.:394
Max. :414
> str(test1)
'data.frame': 29 obs. of 2 variables:
$ yield: int 383 406 351 400 390 361 394 395 414 382 ...
$ seed : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
这下子,是不是感觉好多了。
事实上,对于 test1 的数据集,还有一个问题就是在比较多组个体或观测时,关注的焦点经常是各组的描述性统计信息,而不是样本整体的描述性统计信息。 就像这里我们可能关注的是 test1 里面 seed1、seed2、seed3 这三种种子分别的数据类型,而不是整个 29 个观测的数据结果。关于分组变量,为了不加重大家的学习负担,我推荐可以用我们之前提到过的数据提取方法,从而分别地对数据进行描述。
因为生统的数据通常不会有多个变量这种复杂的数据结构,所以上面的方法已经足够了。如果碰到了多个变量,多个组,可以试试基本包的
aggregate()
函数 或者tidyverse
包的group_by
函数。
事实上,还有一种快速描述数据的函数,即 table
函数。
> table(test1$seed)
1 2 3
10 11 8
可以看到table
可以快速地呈现各个处理所对应的重复数目。三种种子分别有10、11、8个重复。不过 table 似乎在列联表等中更为常见,这里先按下不表,后面在提到线性回归中可能会讲到。
用图画的方式呈现
人类是视觉动物,所以图画的呈现可能远比数据来的更直观。在生统中,我们通常遇见的还是 boxplot
,即箱式图。箱式图对于数据格式的支持非常友好,其支持宽、长数据。
但值得注意的是,对于宽数据,直接把数据输入 boxplot
是没有问题的。因为你每列都代表一个单独的处理。虽然我不太推荐把宽数据作为画图的基本数据,因为其实在不符合各种画图包的格式,也不符合我们做线性回归、方差分析等的格式。这里 boxplot 能画可能只是一个个例。
对于长数据,我们就需要输入 formula,即告诉 boxplot 谁是 x 轴,谁是 y 轴。
让我们拿之前的 test1 和 test2数据来举例子。
# test2的boxplot
boxplot(test2)
Rplot.png
# test1的boxplot,我们以 yield 作为 y 轴,seed 作为 x 轴
# 记得用 ?号看看 boxplot 的基本使用方法
boxplot(yield ~ seed , data = test1)
Rplot01.png
boxplot 的意义参见下图
1 2c21SkzJMf3frPXPAR_gZA.png图片来源:
Understanding Boxplots
你也可以画柱状图,用
hist
这个函数就行。这个上课应该都画过,不讲了。
顺便提一句,现在大家已经开始摈弃bar plot了,因为bar plot并不能给予我们太多的信息。相对应的,大家已经开始逐渐转向 box plot、dot plot(Scatter plot)、violin plot。如果对于画图有兴趣,大家可以去学学 ggplot2。