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

给女朋友写的生统资料_Part5

作者: 城管大队哈队长 | 来源:发表于2019-05-11 16:37 被阅读0次

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

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

    > patientID <- c(1, 2, 3, 4)
    > age <- c(25, 34, 28, 52)
    > diabetes <- c("Type1", "Type2", "Type1", "Type1")
    > status <- c("Poor", "Improved", "Excellent", "Poor")
    > patientdata <- data.frame(patientID, age, diabetes, status)
    > patientdata
      patientID age diabetes    status
    1         1  25    Type1      Poor
    2         2  34    Type2  Improved
    3         3  28    Type1 Excellent
    4         4  52    Type1      Poor
    

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

    > 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
    

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

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

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

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

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

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

    # 先得到索引
    > patientdata$age > 30
    [1] FALSE  TRUE FALSE  TRUE
    > which(patientdata$age > 30)
    [1] 2 4
    
    # 把索引输入 [] 里面
    > patientdata[patientdata$age > 30,]
      patientID age diabetes   status
    2         2  34    Type2 Improved
    4         4  52    Type1     Poor
    > patientdata[which(patientdata$age > 30),]
      patientID age diabetes   status
    2         2  34    Type2 Improved
    4         4  52    Type1     Poor
    
    # 有时候嫌得到索引那步比较长,就可以把索引结果存为一个变量
    > result <- patientdata$age > 30
    > patientdata[result,]
      patientID age diabetes   status
    2         2  34    Type2 Improved
    4         4  52    Type1     Poor
    

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

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

    > test2[result,]
       control   low middle  high
    2    22.91 24.74  28.67 37.94
    4    19.34 19.66  30.28 27.94
    6    23.79 29.10  23.47 34.23
    8    18.53 18.64  29.62 29.13
    10   20.14 25.49  34.64 36.15
    12   19.36 22.69  29.22 24.07
    14   24.13 20.36  35.12 35.24
    

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

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

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

    运算符 描述
    x | y x或y
    x & y x和(且)y

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

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

    # 先得到索引
    > patientdata$age > 30
    [1] FALSE  TRUE FALSE  TRUE
    > patientdata$diabetes == "Type1"
    [1]  TRUE FALSE  TRUE  TRUE
    > patientdata$age > 30 & patientdata$diabetes == "Type1"
    [1] FALSE FALSE FALSE  TRUE
    
    # 提取
    > patientdata[patientdata$age > 30 & patientdata$diabetes == "Type1",]
      patientID age diabetes status
    4         4  52    Type1   Poor
    

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

    > patientdata[patientdata$age > 30,c("age","status")]
      age   status
    2  34 Improved
    4  52     Poor
    

    利用subset来提取

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

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

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

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

    # 年龄大于30岁
    > subset(patientdata, age > 30)
      patientID age diabetes   status
    2         2  34    Type2 Improved
    4         4  52    Type1     Poor
    
    # 年龄大于30,且 I 型糖尿病
    > subset(patientdata, age > 30 & diabetes == "Type1")
      patientID age diabetes status
    4         4  52    Type1   Poor
    
    # 年龄大于30,且 I 型糖尿病的病人的年龄和病情
    > subset(patientdata, age > 30 & diabetes == "Type1",c("age","status"))
      age status
    4  52   Poor
    

    相关文章

      网友评论

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

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