分享

给女朋友写的生统资料_Part4

 生物_医药_科研 2019-07-02

之前我们已经了解了如何去提取行、列数据。这部分我们讲讲如何筛选自己想要的数据。生统常见的一个数据提取问题就是,提取某某处理的那部分数据进行一些检验。比如,在有3种种子的数据中,提取出1号种子对应的数据。这时候,尽管我们可以根据1号种子的数字索引来提取,但这终归不是一个好的方法,因为一旦数据是打乱的,我们就无法知道正确的数字索引,从而进行提取了。所以,这时候,我们就应该使用我们之前讲过的逻辑运算符来进行操作。

顺便提下,我们之前在介绍数据框的时候,把行叫做观测,而把列叫做变量。所以我们在提取行的时候,就是在提取我们感兴趣的观测,而在提取列的时候,就是在提取我们感兴趣的变量。为什么我要翻来覆去地说这个呢,是因为我觉得以行作为观测,列作为变量是一个比较好的呈现数据的方式,也是后面很多我们生统要用到的包需要的格式。也是后面我们在说长宽数据转换时候要再次提到的一点。我们再来看一下糖尿病人的例子。

  1. > patientID <- c(1, 2, 3, 4)

  2. > age <- c(25, 34, 28, 52)

  3. > diabetes <- c('Type1', 'Type2', 'Type1', 'Type1')

  4. > status <- c('Poor', 'Improved', 'Excellent', 'Poor')

  5. > patientdata <- data.frame(patientID, age, diabetes, status)

  6. > patientdata

  7. patientID age diabetes status

  8. 1 1 25 Type1 Poor

  9. 2 2 34 Type2 Improved

  10. 3 3 28 Type1 Excellent

  11. 4 4 52 Type1 Poor

这里是 4 行,就是 4 个观测值,4 个病人。这里有 4 列,4 个变量,就是用 4 个不同地指标去衡量了这些病人。当然,我们也会遇见不是这样格式的数据,比如我们在第五次生统作业上遇见的那个用药的数据集

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

  2. > head(test2)

  3. control low middle high

  4. 1 20.79 22.22 28.56 31.93

  5. 2 22.91 24.74 28.67 37.94

  6. 3 27.21 21.53 25.28 39.76

  7. 4 19.34 19.66 30.28 27.94

  8. 5 17.85 25.89 23.13 29.65

  9. 6 23.79 29.10 23.47 34.23

这个数据集是 15 行,4 列。但我们并不能说我们做了 15 个观测,应用了 4 个变量。实际上,我们根据题目可知,总共是 60 只小鼠,只用了 1 个变量,即用药的浓度。你会发现这个数据集的每一行都不是同一只老鼠,但前面的糖尿病人数据集,每一行都是同一个病人,所以我们可以说每一行都是一个观测。

初次学 R 的人,对于这种数据的结构可能会感到困惑。不过不要紧,数据处理多了,就会慢慢清晰起来。

顺便提一下,现在生物学的数据跟传统社会学的数据有一个很大的不同就是,社会学的数据往往是低维度,高观测,而生物学的数据则恰好相反,是高维度,低观测的。这里的维度指的就是变量。举个例子,比如你要分发问卷给别人来统计大家对你的产品感不感兴趣,你可能在问卷上只有 2 个问题(2个变量,2个维度),但你却分发给了 1w 个人(1w 个 观测)。生物学的例子就好比,你对 100 个植株进行了 50w 个SNP位点的分析,这里就是 100 个观测,50w 的维度。数据结构的不同,就会导致分析方法的不同。

由于生统的数据列数最多也就 4,5 列,加上整列的提取并不需要逻辑运算符,所以后面的提取不涉及到列的提取。同时,为了让大家加深印象,我会交叉地用以及观测这两个名词。

利用 [] 来提取感兴趣的观测

我们之前在向量里面提到过,如何提取符合条件的数据,这里运用的方法也是一样的,也是利用 which 或者 TRUE 来提取。不过在提取数据框数据的时候,我有一个小建议,就是分步完成你的提取任务。我们还是拿糖尿病人的数据集为例子。比如我们希望提取出年龄大于 30 岁的糖尿病人的数据。

  1. # 先得到索引

  2. > patientdata$age > 30

  3. [1] FALSE TRUE FALSE TRUE

  4. > which(patientdata$age > 30)

  5. [1] 2 4

  6. # 把索引输入 [] 里面

  7. > patientdata[patientdata$age > 30,]

  8. patientID age diabetes status

  9. 2 2 34 Type2 Improved

  10. 4 4 52 Type1 Poor

  11. > patientdata[which(patientdata$age > 30),]

  12. patientID age diabetes status

  13. 2 2 34 Type2 Improved

  14. 4 4 52 Type1 Poor

  15. # 有时候嫌得到索引那步比较长,就可以把索引结果存为一个变量

  16. > result <- patientdata$age > 30

  17. > patientdata[result,]

  18. patientID age diabetes status

  19. 2 2 34 Type2 Improved

  20. 4 4 52 Type1 Poor

patientdata$age>30 提取出来的索引值顺利能够放入数据框 [] 的逗号前面是因为我们之前提到过,数据框每列是等长的。想象下,我们有 4 个观测,我们我们用 patientdata$age 提取出来的,实际上是一串有 4 个值的向量,我们对向量进行了逻辑运算符,然后得到了 4 个 TRUE 或者 FALSE值,然后我们就可以把这些 TRUE 或者 FALSE 值和我们的观测一一对应。从而提出我们想要的观测。

事实上,在利用索引提取的时候,我还犯了个小错误,就是把索引输入到了错误的数据框里面,但并没有报错。

  1. > test2[result,]

  2. control low middle high

  3. 2 22.91 24.74 28.67 37.94

  4. 4 19.34 19.66 30.28 27.94

  5. 6 23.79 29.10 23.47 34.23

  6. 8 18.53 18.64 29.62 29.13

  7. 10 20.14 25.49 34.64 36.15

  8. 12 19.36 22.69 29.22 24.07

  9. 14 24.13 20.36 35.12 35.24

这个故事告诉我们的是,索引得到的只是一串数字,他并不跟你产生这个索引结果的数据集有一毛钱的关系。

不要认为 R 的命令是黑箱,一步步地去拆解命令,你就可以很清晰地理解。

如果我们想要两个条件呢,即年龄大于30岁,犯的是 Type I 型糖尿病呢。年龄大于 30 用的是 > ,I 型糖尿病用的是等于 == ,那是什么呢。就是我们之前提到的与或非了。

运算符描述
x \y
x & yx和(且)y

非的话是 !,不等于是 != 。不过我们估计是用不到的,所以我这里也就不讲了。

再次来提取我们想要的观测

  1. # 先得到索引

  2. > patientdata$age > 30

  3. [1] FALSE TRUE FALSE TRUE

  4. > patientdata$diabetes == 'Type1'

  5. [1] TRUE FALSE TRUE TRUE

  6. > patientdata$age > 30 & patientdata$diabetes == 'Type1'

  7. [1] FALSE FALSE FALSE TRUE

  8. # 提取

  9. > patientdata[patientdata$age > 30 & patientdata$diabetes == 'Type1',]

  10. patientID age diabetes status

  11. 4 4 52 Type1 Poor

我们还可以在提取我们想要的观测的同时,提取一部分变量(列)出来

  1. > patientdata[patientdata$age > 30,c('age','status')]

  2. age status

  3. 2 34 Improved

  4. 4 52 Poor

利用subset来提取

前面的那番操作大家可能会感觉写的有点长,那有没有一些简写呢,事实上是有的。你可以利用 R 基本包的 subset 函数来进行跟上面一模一样的操作。

别忘了用 ?来看看这个函数

有些人可能会提到用 attach 这个函数把数据框添加到 R 的搜索路径中,但实际上我不太推荐这样,因为一旦你要完成有许多个数据框的作业,而你又忘了detach,那么很有可能造成你不同数据框的不同变量之间的混淆。

subset 第一个要输入的参数是你的数据框,第二个要输入的参数是你对于观测(行)的筛选,可以用逻辑运算符串联,第三个可选择输入的是你要选择的列(变量)。跟之前一样的筛选条件,不过这次用的是 subset 函数。

  1. # 年龄大于30岁

  2. > subset(patientdata, age > 30)

  3. patientID age diabetes status

  4. 2 2 34 Type2 Improved

  5. 4 4 52 Type1 Poor

  6. # 年龄大于30,且 I 型糖尿病

  7. > subset(patientdata, age > 30 & diabetes == 'Type1')

  8. patientID age diabetes status

  9. 4 4 52 Type1 Poor

  10. # 年龄大于30,且 I 型糖尿病的病人的年龄和病情

  11. > subset(patientdata, age > 30 & diabetes == 'Type1',c('age','status'))

  12. age status

  13. 4 52 Poor

作者:城管大队哈队长

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多