美文网首页
给女朋友写的生统资料_Part6

给女朋友写的生统资料_Part6

作者: 城管大队哈队长 | 来源:发表于2019-05-18 10:02 被阅读0次

前面我们已经讲过了在生统课上会用到基本的数据结构以及怎么来提取我们想要的数据,这一部分我们来讲讲数据的清洗。

在生统课上,我们基本上会遇到两种数据结构。一种是我把其叫做宽数据,就比如我们在第五次生统作业中,碰到的第二题的数据。

> test2 <- read.table("rawdata/test2.txt",header = T)

> 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

这种数据列名其实是不同的处理,每一列都对应不同处理下的值。

实际上,这种数据还不能称之为真正意义上的宽数据,这里拿来指代是为了方便与长数据区分。

另一种就是长数据,也就是我上一节翻来覆去提到过的数据结构。其每一行都是一个观测值,列名则是变量名。典型的就是我们在第五次生统作业中,碰到过的第一题的数据。

> test1 <- read.table("rawdata/test1.txt",header = T)
> head(test1)
  yield seed
1   383    1
2   406    1
3   351    1
4   400    1
5   390    1
6   361    1

由于宽数据在线性回归,方差分析等分析中都无法被函数所识别,所以我们首先讲讲如何把宽数据转换成长数据。

gather函数转换

首先介绍的是 tidyr 包的 gather 函数。tidyr 包的安装就是我们之前讲过的方法

install.packages("tidyr")

有点建议大家直接装 tidyverse 包,这是个各种包的合集,里面还包括了 ggplot2 等。不过有可能安不上 tidyverse , 如果安装有问题,欢迎大家在下面提出问题。

gather 函数的使用非常方便,你只需要指定你转换后的 key 那列的列名,value 那列的列名,以及你需要转成长数据的那几列。我们以 test2 为例。

# 加载包
library(tidyr)

# 使用gahter
> test2_long <- gather(test2, key = "Treatment_dose", value = "survive_time",control, low, middle, high)
> head(test2_long)
  Treatment_dose survive_time
1        control        20.79
2        control        22.91
3        control        27.21
4        control        19.34
5        control        17.85
6        control        23.79

gather 函数你需要输入参数为

  • 第一个参数是你的数据集

  • 第二个参数是你新构建的关键列的名称(该列的内容由原先数据集的列名组成)

    名字自己取,像我这里就取名为"Treatment_dose"

  • 第三个参数是新构建的数值列的名称

    名字还是自己取,我这里取名为"survive_time"

  • 后面的几个参数都是你要用来构建关键列的那几个列名

    这里就是control, low, middle, high,即原来的几个列名。

key 和 value 大家可能还是比较懵逼,但对于我们普通的生统数据,不需要太过于纠结其意义。

gather用法在转换的时候还要考虑uniq key的问题,但我们生统的数据应该也不需要考虑这一点。

也有人提到过用 reshape2 包的 melt 函数,或者基本包 transform 函数来转换。但我觉得没有 gather 这个函数直观,简单。还有,gather 转换的时候对于不等长数据的支持也比较好。就比如我们在第五次生统作业的第三题,药物 1 和 2 有 15 只小鼠,药物 3 只有 10 只老鼠。如果只是单纯地按我们之前的做法读入数据框,就会报错。

> test3 <- read.table("rawdata/test3.txt",header = T)
Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  : 
  line 11 did not have 3 elements

就是因为3列数据不等长,所以R才会报错。这时候,我们就可以设置一个参数

> test3 <- read.table("rawdata/test3.txt",header = T,fill = T)
> test3
   med1 med2 med3
1    40   50   60
2    10   20   30
3    35   45  100
4    25   55   85
5    20   20   20
6    15   15   55
7    35   80   45
8    15  -10   30
9    -5  105   77
10   30   75  105
11   25   10   NA
12   70   60   NA
13   65   45   NA
14   45   60   NA
15   50   30   NA

然后就可以顺利地读入了,而且也可以顺利地用gather函数来整理成长数据。

gather(test3,key = "different_med", value = "weight", med1,med2,med3)

会发现NA还是存在,但我们同样可以设置一个参数

gather(test3,key = "different_med", value = "weight", med1,med2,med3,na.rm = T)

这样,就顺利地转换成我们需要的格式了。

基本包转换

其实,宽数据到长数据的转换,不一定需要特殊的包的函数,也可以用最基本的方法。尽管最基本的方法有些麻烦,但对于提高自己的数据转换能力还是很有帮助的。

rbind和cbind

在使用基本函数转换前,我们先来介绍两个我们以后可能会用到的函数,rbindcbind。rbind是纵向合并,cbind是横向合并。具体操作我们来看一个例子

> data1 <- data.frame(A1 = sample(1:10,3),
+                     A2 = sample(1:10,3),
+                     A3 = sample(1:10,3))
> data1
  A1 A2 A3
1  3  6  2
2  7  9  5
3  5 10  4
> data2 <- data.frame(B1 = sample(10:20,3),
+                     B2 = sample(10:20,3),
+                     B3 = sample(10:20,3))
> data2
  B1 B2 B3
1 15 17 14
2 13 14 11
3 17 15 12

> rbind(data1,data2)
Error in match.names(clabs, names(xi)) : 
  names do not match previous names
> cbind(data1,data2)
  A1 A2 A3 B1 B2 B3
1  3  6  2 15 17 14
2  7  9  5 13 14 11
3  5 10  4 17 15 12

可以看到rbind需要两个数据框有同样的变量(同样的列名),cbind则需要两个数据框的行数是一样的。

rbind尽管需要两个数据框有同样的变量,但顺序不一定要一样,比如

> data3 <- data.frame(A1 = sample(10:20,3),
+                     A3 = sample(10:20,3),
+                     A2 = sample(10:20,3))
> data3
  A1 A3 A2
1 10 12 14
2 11 20 20
3 15 14 19
> rbind(data1,data3)
  A1 A2 A3
1  3  6  2
2  7  9  5
3  5 10  4
4 10 14 12
5 11 20 20
6 15 19 14

这里data1和data3的列名是一样的,但顺序是不一样的,但rbind还是可以合并。

关于rbind和cbind,《R语言实战》4.9也有提到,大家可以去看看

数据转换

介绍完了rbind和cbind,我们就可以来转换数据框了。我用test2做例子

> 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
7    22.60 18.93  28.88 32.63
8    18.53 18.64  29.62 29.13
9    23.23 26.39  24.82 39.62
10   20.14 25.49  34.64 36.15
11   26.71 20.43  22.29 28.85
12   19.36 22.69  29.22 24.07
13   17.22 29.67  25.63 29.29
14   24.13 20.36  35.12 35.24
15   25.85 22.74  32.32 36.13

宽数据转换成长数据,本质上就像堆积木一样。你把每一列的数据拿出来,变成一块积木,然后你就一层层地堆起积木,最后就形成了长数据。是不是感觉特别像rbind干的事情?没错,我们这里就用rbind来构建长数据。

control <- data.frame(Treatment_dose = rep("control",15),
                      survive_time = test2$control)
low <- data.frame(Treatment_dose = rep("low",15),
                      survive_time = test2$low)
middle <- data.frame(Treatment_dose = rep("middle",15),
                      survive_time = test2$middle)
high <- data.frame(Treatment_dose = rep("high",15),
                      survive_time = test2$high)
rbind(control,low,middle,high)

大家可能是一遍遍地打了以上的代码,机智的小伙伴可能还是复制粘贴的,然后把变量名改一下。不过,实际上我们可以用函数来解决这些重复操作的问题。函数这一部分就留待后面讲了。

双因素ANOVA的数据格式整理

在第五次生统作业的最后一题,我们需要考虑的是双因素ANOVA分析。但word文件里面的表格却不是一个双因素ANOVA的格式。让我们来看看如何利用上面讲过的内容,把它变成一个能让 aov 读入的双因素AONVA。

首先复制粘贴A1,A2,A3三列数据到txt文件中,然后读入R中。

> test4 <- read.table("rawdata/test4.txt",header = T)
> head(test4)
     A1    A2    A3
1 282.1 296.7 300.1
2 264.2 318.0 307.5
3 274.2 295.3 294.2
4 276.4 292.8 312.0
5 283.7 304.5 300.2
6 288.0 305.9 292.6

然后转换成长数据框

test4_long <- gather(test4, key = temperature, value = weight, A1, A2, A3)

但这样还不够,这里只有单因素,即饲养温度这一列的信息,还没有饲料的信息。所以我们要自己加上一列饲料的信息。

feed <- c(rep("B1",10),rep("B2",10))
test4_data <- cbind(feed,test4_long)
head(test4_data)

> head(test4_data)
  feed temperature weight
1   B1          A1  282.1
2   B1          A1  264.2
3   B1          A1  274.2
4   B1          A1  276.4
5   B1          A1  283.7
6   B1          A1  288.0

这样就变成了双因素的ANOVA格式,可以顺利让aov函数读入了。

> test4_aov <- aov(weight ~ feed * temperature, data = test4_data)
> summary(test4_aov)
                 Df Sum Sq Mean Sq F value   Pr(>F)    
feed              1    127     127   1.589    0.213    
temperature       2   9080    4540  56.809 5.22e-14 ***
feed:temperature  2     17       9   0.108    0.897    
Residuals        54   4316      80                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

相关文章

  • 给女朋友写的生统资料_Part6

    前面我们已经讲过了在生统课上会用到基本的数据结构以及怎么来提取我们想要的数据,这一部分我们来讲讲数据的清洗。 在生...

  • 给女朋友写的生统资料_Part19

    聚类 聚类(clustering),指将样本分到不同的组中,使得同一组中的样本差异尽可能的小,而不同组中的样本差异...

  • 给女朋友写的生统资料_Part14

    之前我们提到了如果做多次的假设检验,就要考虑多重比较矫正的问题了。那有没有只用做一次检验就可以搞定的方法呢。其实是...

  • 给女朋友写的生统资料_Part15

    相关性 当我们在衡量两个变量的相关关系的时候,我们可以用协方差来进行描述。协方差的公式为 协即协同的意思,X的方差...

  • 给女朋友写的生统资料_Part11

    中心极限定理 中心极限定理 假设我们有一个总体,我们从总体中取出一个大小为5的样本。我们可以利用这个样本均值、方差...

  • 给女朋友写的生统资料_Part12

    我感觉到后面应该会讲的比较省略了,公式模板什么的套的比较多,因为主要是用来做考试复习和速查的。大家如果有什么疑问,...

  • 给女朋友写的生统资料_Part13

    Power(统计功效) 关于power,我觉得下面这张图已经解释的很好了。 当 H0 是正确的时候,拒绝了H0,就...

  • 给女朋友写的生统资料_Part16

    多元线性回归 多元线性回归的方程写为:其中代表第个预测变量,是对应的模型参数。可以解释为在所有其他预测变量保持不变...

  • 给女朋友写的生统资料_Part17

    逻辑斯蒂回归 我们之前提到的线性回归是利用X来预测Y,Y是连续型的数值变量。但有时候Y并不是连续型的变量,而是一种...

  • 给女朋友写的生统资料_Part18

    apply和function 差异基因的检验估计会用到function和apply。不过差异基因表达的functi...

网友评论

      本文标题:给女朋友写的生统资料_Part6

      本文链接:https://www.haomeiwen.com/subject/jzmzaqtx.html