哈佛R语言课程--5.数据框、矩阵、列表取子集
学习目标
- 演示如何从现有的数据结构中取子集,合并及创建新数据集。
- 导出数据表和图以供在R环境以外使用。
1.数据框
数据框(和矩阵)有2个维度(行和列),要想从中提取部分特定的数据,就需要指定“坐标”。和向量一样,使用方括号,但是需要两个索引。在方括号内,首先是行号,然后是列号(二者用逗号分隔)。以metadata
数据框为例,如下所示是前六个样本:
例如:
metadata[1, 1] # element from the first row in the first column of the data frame
metadata[1, 3] # element from the first row in the 3rd column
现在,如果只想选择行,可以提供行的索引,将列索引留空。关键是要写逗号,让R知道你正在访问二维数据结构:
metadata[3, ] # vector containing all elements in the 3rd row
如果从数据框中选择特定列,则行保留为空白:
metadata[ , 3] # vector containing all elements in the 3rd column
像向量一样,也可以一次选择多行多列。在方括号内,提供所需值的向量:
metadata[ , 1:2] # dataframe containing first two columns
metadata[c(1,3,6), ] # dataframe containing first, third and sixth rows
对于较大的数据集,不易记住与特定变量对应的列号。在某些情况下,如果使用的脚本添加或删除列,则变量的列号可能会更改。因此,最好使用列名来引用特定变量,这样可以使代码更易于阅读,并且您的意图更加清晰。
metadata[1:3 , "celltype"] # elements of the celltype column corresponding to the first three samples
还可以使用$
符号选择特定列,对特定列执行操作。在这种情况下,整个列是向量。例如,要从metadata数据集中提取所有基因型,可以使用:
metadata$genotype
可以用colnames(metadata)
或names(metadata)
显示列名称。然后我们可以提供索引以从该向量中选择特定值。例如,如果我们想要前五个样本的基因型信息metadata
:
colnames(metadata)
metadata$genotype[1:5]
将$
允许你通过名称来选择一列。要按名称选择多个列,需要连接与列名对应的字符串向量:
metadata[, c("genotype", "celltype")]
genotype celltype
sample1 Wt typeA
sample2 Wt typeA
sample3 Wt typeA
sample4 KO typeA
sample5 KO typeA
sample6 KO typeA
sample7 Wt typeB
sample8 Wt typeB
sample9 Wt typeB
sample10 KO typeB
sample11 KO typeB
sample12 KO typeB
虽然没有等效的$
语法来按名称选择行,但可以使用行名称选择特定的行。要查看行的名称,用rownames()
函数:
rownames(metadata)
metadata[c("sample10", "sample12"),]
选择使用带有逻辑运算符的索引
对于与向量类似的数据集,我们可以使用数据集中特定列的逻辑向量来仅选择数据集中的行,其中TRUE值与逻辑向量中的位置或索引相同。然后用逻辑向量返回数据框中的所有行,其中这些值为TRUE。
idx <- metadata$celltype == "typeA"
metadata[idx, ]
使用which()
函数选择具有逻辑运算符的索引
which()
函数可以返回逻辑表达式为TRUE的索引。例如,metadata
数据框中celltype
是typeA
的行:
idx <- which(metadata$celltype == "typeA")
metadata[idx, ]
或者提取metadata重复2和3的索引:
idx <- which(metadata$replicate > 1)
metadata[idx, ]
将此输出保存到变量:
sub_meta <- metadata[idx, ]
练习
metadata
数据框取子集,返回基因类型为KO
的行。
注意:有更简单的方法可以使用逻辑表达式对数据帧进行子集化,包括
filter()
和subset()
函数。这些函数将返回逻辑表达式为TRUE的数据帧的行,允许我们在一个步骤中对数据进行子集化。我们将filter()
在后面的课程中更详细地探讨该功能。
2.列表
从列表中选择组件需要略有不同的表示法,即使理论上列表是向量(包含多个数据结构)。要选择列表的特定组件,您需要使用双括号表示法[[]]
。使用之前创建的list1
,并索引第二个组件:
list1[[2]]
你看到控制台上输出了什么?使用双括号表示法对于访问各个组件同时保留原始数据结构非常有用。创建此列表时,我们知道我们最初在第二个组件中存储了一个数据框。通过class
功能,可以检查提取后是否是数据框:
comp2 <- list1[[2]]
class(comp2)
还可以通过后接方括号来引用组件内部的内容。例如,在第一个组件中,我们存储了一个向量。
list1[[1]]
[1] "ecoli" "human" "corn"
引用该向量的第一个元素,使用:
list1[[1]][1]
[1] "ecoli"
也可以对数据框和矩阵执行相同的操作,但是对于较大的数据集,建议不要这样做。相反,最好将列表组件的内容保存到变量(如上所述)并进一步操作它。此外尤其要注意,在选择组件时,我们一次只能访问一个组件。要访问列表的多个组件,请参阅下面的注释。
注释:使用单括号表示法也适用于列表。不同之处在于检索的信息类别。使用单括号表示法
list1[1]
将以列表形式而不是原始数据结构返回内容。这种表示法的好处是它允许通过向量进行索引,因此您可以一次访问列表的多个组件。
练习
让我们练习检查清单。创建一个名为random
的列表,包含组件:metadata
,age
,list1
,samplegroup
,和number
。
-
打印出
samplegroup
组件中存储的值。 -
从
metadata
列表的组件中提取celltype
列。从celltype值中仅选择最后5个值。
为列表中的组件命名有助于识别每个列表组件包含的内容,也更容易从列表组件中提取值。
列表的组件命名数据框的列命名使用的函数都是names()
。
查看list1
组件的名称:
names(list1)
创建列表时,将species
向量与数据集df
和向量number
组合在一起。用原始名称给组件命名:
names(list1) <- c("species", "df", "number")
names(list1)
命名了列表组件后,可以使用$
来提取组件,与数据框提取列相似。要使用名称提取组件,使用list_name$component_name
:
从列表中提取df
数据框list1
:
list1$df
现在有三种方法可以从列表中提取组件。从list1
中提取species
:
list1[[1]]
list1[["species"]]
list1$species
练习
练习结合从目前为止我们所讲过的数据结构中提取数据的方法:
- 设置在上一个练习中创建的列表
random
的名称。 - 从
random
列表中提取向量age
的第三个元素。 - 从
random
列表中的数据框metadata
中提取基因型信息。
3.导出文件
到目前为止只修改了R中的数据; 文件保持不变。想要将数据集保存到文件,需要使用函数write
。
要以逗号分隔的格式(.csv)将矩阵导出为文件,可以使用write.csv
函数。有两个必需参数:要导出的数据结构的变量名称,以及要导出到的路径和文件名。默认情况下用逗号分隔列:
write.csv(sub_meta, file="data/subset_meta.csv")
与读取数据类似,有多种功能可供用户以特定格式导出数据。write.table
也是常用的导出函数,允许用户指定要使用的分隔符。此函数通常用于创建制表符分隔的文件。
注意:有时在将具有行名称的数据框写入文件时,列名称将从行名称列开始对齐。为避免这种情况,可以在导出文件时设置参数
col.names = NA
,以确保所有列名称都与正确的列值对齐。
将向量写入文件需要与数据框的函数不同。使用write()
,例如:
write(glengths, file="data/genome_lengths.txt", ncolumns=1)
用于数据处理的R包
上面介绍的方法使用基本R函数进行数据处理。稍后探索Tidyverse套件,专门用于简化数据处理。