主讲老师第三课:R 语言基础知识
接下来,我们开始 R 语言基础知识部分的讲解内容。首先来看一下几种常见数据类型和变量结构
1.常量
在数据类型中,我们最常见的主要是三类形式,分别是数值型 numeric,字符型character,以及逻型 logical。此外,R 语言也支持缺失值的存在。
1)顾名思义,数值型就是指数字形式的类型,数值型常量包括整型、单精度、双精度等,一般不需要区分。写法如 123, 123.45, -123.45, -0.012, 1.23E2, -1.2E-2等,同时, 为了表示 123 是整型,可以写成 123L(不需要细究)2)与之对应的是字符型,有一个十分显著的特征,就是单引号(' ')或者引号(" "),不管引号内的内容有多长,或者引号内是数字,字母,亦或者是一段话,它都属于字符型变量,比如"Li Ming"或'Li Ming',当然,字符型支持中文,如"李明"或'李明'。
目前,国内的中文编码主要有 GBK 编码和 UTF-8 编码,有时会遇到编码错误造成乱码的问题,在 R 软件内字符串一般用 UTF-8 编码保存编码问题不需要过度深究,这个涉及到计算机语言的组成3)逻辑型常量只有 TRUE 和 FALSE;4)缺失值用 NA 表示,统计计算中经常会遇到缺失值,表示记录丢失、因为错误而不能用、节假日没有数据等,注意: R 支持特殊的 Inf 值,这是实数型值,表示正无穷大,不算缺失值
2.变量
在 R 中,变量可以保存所有的数据类型, 包括向量、矩阵、数据框、函数等,变量都有变量名,注意,变量名必须以字母、数字、下划线和句点组成, 变量名的第一个字符不能取为数字,另外,变量名是区分大小写的, y 和 Y 是两个不同的变量名。通过赋值符号 <-,可以将向量赋值给一个新的变量名,用<-赋值的方法定义变量,<-也可以写成=,但是<-更直观。关于赋值符号,有一个快捷键,Alt和-联用。
如何更加直观的理解变量?
一把钥匙开一扇门,且一看到钥匙就知道要开哪扇门把里面的代码 R 语言基础知识板块.R 发给大家,在此,我们可以快速的进行判断,其中变量 x1 是数值型,x2 和 x3 均是字符串型,x4 是逻辑型。R 的变量没有固定的类型,给已有变量赋值为新的类型, 该变量就变成新的类型,但是一般应该避免这样的行为R 是“动态类型”语言, 赋值实际上是“绑定”的过程,换句话说,将一个变量名与一个存储地址联系在一起, 但同一个存储地址可以有多个变量名与其联系,对于数据类型的判断,也是一个重要的内容,虽然简单,但后面很容易因为不注意而报错,一旦数据信息变得复杂多变,肉眼判断已经无法满足要求。此时,我们一般需要使用**class()**函数来进行判断,对于 class()函数的使用,直接将需要判断的内容写在括号里即可运行的结果和我们前面的判断是一致的。
3.数据结构及变量的生成
R 语言的存在是为了能够处理大输出而存在的,其绝对不仅仅只是前面内容中单个的数据类型,对于单个数据大可通过 EXCEL 直接进行处理,毕竟,从头学习一门新的分析语言,其成本可一点不低。在 R 语言中,多个数据类型进行组合,即可形成数据结果,常见的数据结构包括以下几种:向量,数据框,矩阵,列表,数组等等。先来简单介绍一下最常用的一个数据结构之间的关系,向量。
在 R 中数据框约等于我们常说的“表格”,但是区别在于数据框中一列只有有一种数据类型,而数据框中单独一列拿出来,就是一个向量。
3.1 向量(Vector)
3.1.1 向量的生成
向量是将若干个基础类型相同的值存储在一起, 各个元素可以按序号访问。如果将若干个数值存储在一起可以用序号访问,就叫做一个数值型向量。对于向量而言,一个向量只允许存在一种数据类型,但是允许有重复值的存在,除了上述提到的直接从数据框中提取一列作为一个整体来生成向量外,我们先来讲一下如何生成一个向量。
1). 用 c()函数把多个元素或向量组合成一个向量,c 即 cbind 结合的意思。
这里,需要注意几点:
⚫ 如果生成一个字符型向量时,每一个元素都要加上引号(" ");⚫ 数据类型转换的优先顺序;当一个向量中存在两种及以上变量类型时,存在优先级,即字符型>数值型>逻辑型。
如逻辑变量和数值型在一起时,TRUE 会自动转换为 1,FALSE 为 0,而只要有字符型存在,所有都会变成字符型⚫ c()函数生成方式一般仅限于少量元素的使用2). 连续的数字用冒号(:)使用冒号,直接可以生成一串连续的数字。1:20 这样的写法表示从 1 到 20 的整数组成的向量。用 print()函数显示向量或在命令行中显示向量时, 每行显示的行首会有方括号和数字序号, 代表该行显示的第一个向量元素的下标通过 length(x)可以求向量 x 的长度,其中长度为零的向量表示为 numeric(0)numeric()函数可以用来初始化一个指定元素个数而元素都等于零的数值型向量,如 numeric(10)会生成元素为 10 个零的向量3). 相关函数的使用有重复内容的使用 rep()函数,有规律的使用 seq()函数,随机数使用 rnorm()函数第一个 rep()函数,将 gene 直接重复了三遍,rep() 函数不给循环次数,默认 1 次;seq(from=1,to=15,by=3)命令表示从 1 开始,15 结束,每隔 3 取数,这也是我们最熟悉的“等差数列”而 rnorm(n=3)则是随机生成 3 个数字,甚至前后两次运行得到的结果都是不一样的。
简单介绍一下,seq()函数其实是冒号运算符的推广,比如,seq(5)等同于 1:5,seq(2,5)等同于 2:5,seq(11, 15, by=2)产生 11,13,15。当然,在使用变量名时次序可以颠倒,比如 seq(to=5, from=2)}仍等同于 2:5另外,有一点技术性的小问题,(1). 1:5 和 seq(5)的结果是整型(integer)的,(2). c(1,3,5)和 seq(1, 5, by=2)的结果是浮点型(double)的,这个区别了解即可。
rep()函数用来产生重复数值,为了产生一个初值为零的长度为 n 的向量,用 x <-rep(0, n)。rep(c(1,3), 2)把第一个自变量重复两次, 结果相当于 c(1,3,1,3)。
同时,给大家补充一个内容,rep(c(1,3), c(2,4))需要利用 R 的一般向量化规则,把第一自变量的第一个元素 1 按照第二自变量中第一个元素 2 的次数重复, 把第一自变量中第二个元素 3 按照第二自变量中第二个元素 4 的次数重复,结果相当于c(1,1,3,3,3,3)。如果希望重复完一个元素后再重复另一元素,可以用 each=选项,比如 rep(c(1,3), each=2)结果相当于 c(1,1,3,3)。
4). 组合使用生成复杂的向量,比如将第 2 种和第 3 种方式进行组合使用关于 paste0()函数,是将前后两个重复的向量进行拼接,最后形成新的变量内容。
对此方法,需要注意一点,即向量的连接,哪个长则以哪个为准
3.1.2 标量和标量运算
单个数值称为标量,在 R 语言里没有单独的标量类型, 标量实际是长度为 1 的向量,R 中四则运算用+ - * / ^表示(加、减、乘、除、乘方),而且,R 中四则运算仍遵从通常的优先级规则, 可以用圆括号()改变运算的先后次序。
除了加、减、乘、除、乘方, R 还支持整除运算和求余运算,用%/%表示整除,用%%表示求余。
3.1.3 向量与标量运算
生成的向量可以进行相应的数学运算。向量与标量的运算为每个元素与标量的运算。
一个向量乘以一个标量, 就是线性代数中的数乘运算,如果四则运算时存在缺失值,那么缺失元素参加的运算相应结果元素仍缺失
3.1.4 等长向量运算
对于等长向量的运算,其过程为对应元素两两运算。
通过 c()函数生成两个等长的向量可以看到,两个等长向量的加、减运算就是线性代数中两个向量的加、减运算。
3.1.5 不等长向量的运算
而对于两个不等长向量的四则运算, 可以分成两种情况:1). 如果其长度为倍数关系,规则是每次从头重复利用短的一个将短的向量 x1 进行一轮重复,形成等长向量,然后进行计算,当然,注意一点,不仅是四则运算,R 中有两个或多个向量按照元素一一对应参与某种运算或函数调用时, 如果向量长度相同,一般都采用这样的规则。
2). 如果两个向量的长度不是倍数关系,尽管系统会给出警告信息,但仍旧遵循循环计算的原理进行。
这里注意,在 R 语言里面,Warning 警告不算报错,继续运行即可,只有 Error 的出现才会认为报错。
3.1.6 向量函数
3.1.6.1 向量化的函数
R 中的函数一般都是向量化的,在 R 中, 如果普通的一元函数以向量为自变量,一般会对每个元素计算。
当进行计算时,会对其中每一个向量进行开方处理,常用的数学函数有:
关于这些函数的使用,和普通的线性运算原理基本类似。
3.1.6.2 排序函数
此外,我们来介绍几个用于排序的函数:
sort(x)返回排序结果rev(x)返回把各元素排列次序反转后的结果order(x)返回排序用的下标例子中, order(x)结果中 3 是 x 的最小元素 11 所在的位置下标,1 是 x 的第二小元素 33 所在的位置下标,2 是 x 的最大元素 55 所在的位置下标。这里是和Python 这些语言的不同之处,R 里面第一个元素的下标是 1,而不是 0。在 R 里面,下标是直接 1,2,3 往下的。
3.1.6.3 统计函数
sum(求和), mean(求平均值), var(求样本方差), sd(求样本标准差), min(求最小值),max(求最大值), range(求最小值和最大值)等函数称为统计函数。
这些函数后面在分析过程中都会有用到,到时候再逐个进行介绍。还有一些其他函
数:交集、并集、差集
3.1.7 逻辑型向量
逻辑型是 R 的基本数据类型之一,只有两个值 TRUE 和 FALSE, 缺失时为 NA,逻辑值一般产生自比较,向量比较后的输出结果为逻辑型向量。
这个也是向量循环的一个应用,R 里面会自动进行循环补充,向量与标量的运算是向量每个元素与标量都分别运算一次,等长向量的运算时对应元素的运算,不等长但长度为倍数关系的向量运算是把短的从头重复利用,但是,与 NA 比较产生 NA。
这里注意一个符号,在 R 里面,=表示赋值的含义,而==表示判断是否相等,其最后输出的是逻辑变量,此外,为了判断向量每个元素是否 NA, 用 is.na()函数。
同理,用 is.finite()判断向量每个元素是否 Inf 值,常见的比较运算符包括以下几种分别表示小于、小于等于、大于、大于等于、等于、不等于、属于。我们来介绍一下最后一个重点知识点内容,%in%。
%in%是一种比较特殊的比较,x %in% y 的运算把向量 y 看成集合, 运算结果是一个逻辑型向量,它表示对 x 中的每个元素进行判断,判断其是否存在于 y 中,无论位置。
来看几个例子,c(1,3) %in% c(2,3,4),它依次比较 1 是否在后面的向量中,输出第一个结果,比较 3 是否存在后面的向量中,输出第二个结果,因此,最后输出结果向量的长度是与第一个向量等长的,结果是[1] FALSE TRUE;再来看一个例子,c(NA,3) %in% c(2,3,4)对于%in%的使用,大家去理解一下,后面会一直使用。
x %in% y,其含义是比较 x 向量中每个元素是否在 y 向量中存在,而与之对应的,还存在着另外一个类似的函数,match(x, y)函数。
match(x, y)函数的含义同样是查看 x 向量中每个元素是否在 y 向量中存在,但是,两者的区别在于 match(x, y)函数对 x 的每个元素,找到其在 y 中首次出现的下标,
如果找不到,则返回 NA。看个例子:
match(c(1, 3), c(2,3,4,3))分别查看 1 和 3 是否在后面存在,如果存在,输出首次出现的下标,那么,它的输出结果是[1] NA 2。关于这两个函数,大家课后再回顾一下,后面在 TCGA 数据整理和绘图中都会经常用到。接下来,我们看下逻辑运算.
3.1.8 逻辑运算
为了表达如“而且”, “或者”之类的复合比较,需要使用逻辑运算把两个比较连接起来。
逻辑运算符为&, |和!, 分别表示“同时成立”、“两者至少其一成立”、“取反”。比如,设 age<=3 表示婴儿,sex=='女'表示女性,那么则 age<=3 & sex=='女'表示女婴,age<=3 | sex=='女'表示婴儿或妇女,!(age<=3 | sex=='女')表示既非婴儿也非妇女。为了确定运算的先后次序可以用圆括号()指定用 xor(x, y)表示 x 与 y 的异或运算,解释一下,当值不相等时为真值,相等时为假值,有缺失值参加运算时为缺失值。另外,&&和||分别为短路的标量逻辑“与”和短路的标量逻辑“或”,一般用在 if 语句、while 语句中, 且只要第一个比较已经决
定最终结果就不计算第二个比较。看个例子:
在这个过程中,其中的 sqrt(-1)部分不会执行,因为第一个标量的结果为 TRUE,所以第二部分没有参加计算,否则的话第二部分的计算会因为函数自变量范围错误而报错。
3.1.9 逻辑运算函数
下面,来看几个十分常用的函数
3.1.9.1 which 函数
函数 which()返回真值对应的所有下标。
which(c(FALSE, TRUE, TRUE, FALSE, NA))在这里,第 2 和 3 个元素为 TRUE,因此,其输出结果为 2 和 3。
同理的,在 11 到 15 中,第 3,4,5 个元素是 TRUE,输出结果也是 3,4,5
3.1.9.2 identical(x,y)函数
函数 identical(x,y)比较两个 R 对象 x 与 y 的内容是否完全相同,这里需要注意的是必须完全相同,包括顺序,字符类型等等。
再看一个例子,identical(c(1L,2L,3L), c(1,2,3)),其中 1L 这种写法在昨天讲过,L表示的是整数型,1L 就是 1,但是,最后的输出结果为 FALSE,因为后一向量是实数型。而与之对应的,还有另外一个函数,all.equal()函数,函数 all.equal()与 identical()类似, 但是在比较数值型时不区分整数型与实数型,当相同时会返回标量 TRUE
3.1.9.3 duplicated()函数
函数 duplicated()返回每个元素是否为重复值的结果,注意一点,当一个变量第一次出现时,其为 FALSE,第二次及以后出现时为 TRUEduplicated()函数在实际应用中常常与取反符号!相互联用,!duplicated()可以去到显示重复值的作用,进一步降重,当然,用函数 unique()可以返回去掉重复值的结果。
3.1.10 字符型向量
字符型向量是元素为字符串的向量注意,空字符串并不能自动认为是缺失值,字符型的缺失值仍用 NA 表示。
3.1.10.1 paste()函数
关于 paste()函数的使用,可以和昨天介绍的 paste0()函数一起学习,paste()用来连接两个字符型向量, 元素一一对应连接,其默认元素之间用空格连接。
paste(c("ab", "cd"), c("ef", "gh")),其输出的结果是 c("ab ef", "cd gh")。
当然,paste()函数在连接两个字符型向量时采用 R 的一般向量间运算规则,可以作一对多连接,paste("x", 1:3),根据向量自动循环补齐的原理,结果相当于 c("x1", "x 2", "x 3")。
如果我们想换一个中间的连接符号,可以对参数 sep 进行调整,用 sep=指定分隔符。paste("x", 1:3, sep=""),这样,最后的输出结果就是 c("x1", "x2", "x3")。而此时,当 sep=""时,paste()函数就等于来 paste0()函数的作用。另外,使用collapse=参数可以把字符型向量的各个元素连接成一个单一的字符串。
paste(c("a", "b", "c"), collapse=""),最后的结果相当于"abc"。
3.1.10.2 转换大小写
toupper()函数把字符型向量内容转为大写,tolower()函数转为小写。比如,toupper('aB cd')结果为"AB CD",tolower(c('aB', 'cd'))结果相当于 c("ab" "cd")。
注意:这两个 函 数 可 以 用 于 不 区 分 大 小 写 的 比 较 , 不 论 x 的 值 是 'JAN','Jan' 还 是 'jan' ,toupper(x)=='JAN'的结果都为 TRUE。
3.1.10.3 字符串长度
用 nchar(x, type='bytes')计算字符型向量 x 中每个字符串的以字节为单位的长度,这一点对中英文是有差别的, 中文通常一个汉字占两个字节,英文字母、数字、标点占一个字节。
3.1.10.4 取子串
substr(x, start, stop)从字符串 x 中取出从第 start 个到第 stop 个的子串,举个
例子:
如果 x 是一个字符型向量,substr 将对每个元素取子串此外,用 substring(x, start)可以从字符串 x 中取出从第 start 个到末尾的子串
3.1.10.5 字符串拆分
用 strsplit()函数可以把一个字符串按照某种分隔符拆分开。
比如,存在这样一个向量,x <- '10,8,7',我们需要按逗号对他进行拆分,strsplit(x,',', fixed=TRUE)[[1]],最后,其输出结果是[1] "10" "8" "7"。
关于 strsplit()函数的具体应用,我们后面在 id 转换时会有一个很详细的例子。
另外,对于 strsplit()的结果,其输出结果是一个列表,对于这部分基础变量的内容,先简单介绍到这里,大家先了解熟悉一下。
3.2 矩阵型(Matrix)和数据框型(Data Frame)
下面来看一下矩阵和数据框两种结构。关于这两种结构类型,两个长的基本相同,但是矩阵和向量有些许不同,矩阵只允许一种数据类型存在,而数据框允许多种数据类型存在。
3.2.1 矩阵
先讲一下如何通过向量来生成矩阵,这里介绍两种方法。
1). matrix()函数使用 matrix()函数生成 1 到 9,并将其分成 3 行,matrix()函数把矩阵元素以一个向量的形式输入,用 nrow 和 ncol 规定行数和列数。
2). cbind()函数若 x1, x2, x3 是等长的向量, cbind(x1, x2, x3)把它们看成列向量并在一起组成一个矩阵。cbind()的变量内容可以同时包含向量与矩阵,向量的长度必须与矩阵行数相等。
rbind()用法类似, 可以等长的向量看成行向量上下摞在一起
3.2.2 矩阵运算
3.2.2.1 四则运算
矩阵可以与标量作四则运算,结果为每个元素进行相应运算可以看到,其中每个元素都在原来基础上加了 2两个同形状的矩阵进行加、减运算, 即对应元素相加、相减,用 A + B,A - B 表示可以看到,这就是线性代数中矩阵的加、减运算,对两个同形状的矩阵, 用*表示两个矩阵对应元素相乘(注意这不是线性代数中的矩阵乘法), 用/表示两个矩阵对应元素相除。
3.2.2.2 矩阵乘法
用%*%表示矩阵乘法而不是用*表示,同时注意矩阵乘法要求左边的矩阵的列数等于右边的矩阵的行数。
关于矩阵乘法,了解一下就可以了,基本不会用到。
3.2.3 数据框
数据框型是 R 里面最为常见的类型。统计分析中最常见的原始数据形式是类似于数据库表或 Excel 数据表的形式,这样形式的数据在 R 中叫做数据框(data.frame)数据框类似于一个矩阵,有行、列, 但各列允许有不同类型:数值型向量、因子、字符型向量、日期时间向量,但是,同一列的数据类型相同在 R 中数据框是一个特殊的列表, 其每个列表元素都是一个长度相同的向量,事实上,数据框还允许一个元素是一个矩阵或者列表,这个特殊情况先有个印象,后面在 TCGA 数据清洗部分会有出现。
关于数据框的来源,可以分成:
1.在 R 中新建;
2.由已有数据转换或处理得到;
3.从文件中读取;
4.内置数据集,包括常用的 iris,mtcars 数据集等等
这里需要注意一点,不要在内置数据集上修改内容,一旦修改,它会永远保存下来的,除非卸载重新装 R
下面,我们先来新建一个简单的数据框:
函数 data.frame()可以生成数据框,注意一点,data.frame()函数会将字符型列转换成因子形式,如果不需要,我们一般会加选项 stringsAsFactors=FALSE 可以避免这样的转换。
还有一点,如果数据框的某一列为常数,可以在 data.frame()调用中仅给该列赋一个值,生成的结果会自动重复这个值使得该列与其他列等长点击 Environment 中的 df,即可打开新生成的数据框。来看一下数据框在 R 中打开后的形式。
可以看到,红色方框内的字体呈明显加粗的形式,这分别是表格的行名(rownames)和列名(colnames),与 EXCEL 中不同的是,R 语言内 rownames 和colnames 均不属于正文内容简单来说,第一列和第一行并不是红色框内的内容,而是其往后的那一列和一行。
关于数据框,有几个常用函数dim()是返回数据框中有几行几列;nrow(df)求 df 的行数,ncol(df)或 length(df)求 df 的列数给 rownames(df)或 colnames(df)赋值可以修改列名。
4.数据与变量类型的判断与转换
对于数据类型或者变量结构的判断和转换,我们可以使用两大经典大家族函数,分别是 is 家族函数和 as 家族函数is 家族函数,其主要作用是进行判断,最终返回 TRUE 或者 FALSE 的逻辑值。整个函数的含义相当直接,是谁谁谁吗?返回一个是或者不是as 家族函数,其主要功能就是将数据或变量的类型转换为相对应的形式当然,is 和 as 家族函数远不止展示的这些,我们掌握了整个函数的基本含义后,就可以根据需要进行使用了,并且,大家对相应函数的名字也不需要都去记住。两个家族函数各自有 20 来个成员。这里教个小技巧,输入 as 后,按一下键盘上的
tab 键,即可出现所有可能的函数:
同时,将鼠标移到对应的函数上后,还会有相应的介绍出现。这样一来,直接根据需要进行选择就可以了
5.变量取子集
变量取子集,是一个十分重要的知识点,在后面数据整理和分析过程中将发挥出重要的作用。在分析数据时,我们经常要对数据进行分选,以便只处理选定的列或行,也就是我们在 EXCEL 中最常使用的筛选功能,由于数据框或矩阵只是组合在一起的向量集合,因此,我们从向量开始,学习如何访问不同的元素,然后将这些概念扩展到数据框。
本质上来说其实就是整理数据的技能,我们要把我们的数据整理成别人要求的形式
5.1 向量取子集
关于向量取子集,可以分成两种类型,第一种是根据索引的下标进行查找,第二种是根据逻辑判断值来进行提取
5.1.1 选择使用索引
从向量中提取一个或多个值,可以使用方括号[ ]语法提供一个或多个索引,索引(index)表示一个向量中的元素数目。在 R 里面,索引从 1 开始,符合人类的常用思维模 式。
首先,创建一个名为 x 的向量:
相对应的,在向量中,15 的索引为 1,22 的索引为 2,以此类推,那么,如果我们想提取这个向量的第五个值。
想提取除了这个向量中第五个值之外的所有值如果我们想要选择多个元素,我们仍然会使用方括号语法,但不是使用单个值,而是传递几个索引值的向量提取第 3,5,6 个值。
如果要从向量中选择一系列连续值,使用:这个是一个特殊函数,它以递增或递减
顺序创建整数数字向量,让我们从向量 x 中选择前四个值:
5.1.2 选择使用带有逻辑运算符的索引
此外,我们也可以使用带有逻辑运算符的索引,常见的逻辑运算符包括大于(>),小于(<),等于(==),不等于(!=)。如果想知道 x 向量中大于 50 的元素:
通过 idx <- x > 50 获得由一串逻辑变量组成的向量,然后取子集,取出为 TRUE 的值。再给一个复杂一点的内容,选取 x 向量中大于 50 或小于 18 的元素:
这里需要另外一个符号|,表示或,&表示和,这个实际上和数学中的原理是比较类似的这样,最后得到结果。虽然这样通过逻辑表达式将返回相同长度的 TRUE 和 FALSE值的向量,但是我们还有另外一种方法。
5.1.3 使用 which()函数使用逻辑运算符进行索引
虽然逻辑表达式可以返回相同长度的 TRUE 和 FALSE 值的向量,但可以使用which()函数直接输出结果值为 TRUE 的索引先通过 which 函数返回一串判断为 TRUE 的索引,然后再和普通索引取子集一样进行取子集操作。
这样,到此,我们讲了三种方法第一种直接输入索引第二种通过逻辑判断得到 TRUE 和 FALSE第三种是使用 which()函数,但是,无论是否使用 which(),还是其他任一方法建立索引,都会得到相同的结果,使用哪种方法取决于个人偏好,并且,熟悉以后,还可以使用嵌套函数来简化整个内容,结果与上方的 x[idx]是相同的,直接把代码写成一行即可。
讲到这里,关于向量提取大家可以理解吗?一种是直接取值,一种是索引,一种是which 函数,哪种方便选择哪种
5.2 数据框取子集
数据框和矩阵有 2 个维度(即行和列)。要想从中提取部分特定的数据,就需要指定“坐标”,和向量一样,使用方括号[]。但是,需要提供两个索引,在方括号内,首先是行号,然后是列号,二者用逗号分隔[,]。
如果选择第 2 行第 2 列的元素,可以直接通过[2,2]给予定位进行寻找。
如果只想选择行,可以提供行的索引,将列索引留空,这里有个关键,需要写逗号,逗号可以让 R 知道你正在访问二维数据结构。
这样输出的结果就是第二行。同样道理,如果从数据框中选择特定列,则行保留为空白除了写第几列或者第几行外,我们也可以写列名或者行名。比如这样可以直接提取列名为 gene 的一整列,其输出结果和 df[,2]是一样的。
当然,和向量一样,也可以一次选择多行多列,在方括号内,提供所需值的向量。
可以在 Environment 中查看对于较大的数据集,不易记住与特定变量对应的列号,并且,在某些情况下,如果使用脚本添加或删除列,则变量的列号可能会更改,因此,最好使用列名来引用特定变量,这样可以使代码更易于阅读,并且您的意图更加清晰。
此外,对于数据框格式,还可以使用$符号选择特定列,对特定列执行操作此时,选中的是数据框 df 中名为 gene 的整列。对于与向量类似的数据集,我们也可以 使用数据集中特定列的逻辑向量来仅选择数据集中的行,然后用逻辑向量返
回数据框中的所有行,其中这些值为 TRUE。举个例子:
另外,还有一个列表的类型,其取子集的方式是[[]],比如列表中第一个元素[[1]],第二个[[2]],这一部分知识点希望大家能先理解了,后期在 TCGA 数据集清洗的时候,几百列加几万行的取子集操作,不要晕了。
下面,补充一个比较常用的函数家族 apply()家族,后面经常会用到,所以给大家补充一下。对于 apply 函数,主要用于数据汇总,关于数据汇总,就是按照分类水
平,对数据进行整理和分析。在这里,先来看个数据集:
运行以后,可以看到环境变量中多了个名为 iris 的数据内容,点击看下里面的内容。
这是一个十分常用的内置数据集,是鸢尾花的一些数据内容,后面画图也会常常用到它,一共 5 列。
通过 str()函数可以看下这个数据集的整体情况,其中,最后一个 Species 是分类变量,同时是个因子水平 facter。
前面四列,分别是花的四个参数,根据 Species 变量的不同类型,计算其他相应变量的平均数,标准差等一系列运算过程,这个过程就是数据汇总。
5.3 apply()家族
对于数据汇总,其中一个鼎鼎大名的就是 apply()函数家族。对于 apply 家族,是由几个名字类似,且发挥相似功能的几个函数所组成的函数组合在该家族中,最常用的自然是老大 apply()函数,后面还包括了几个常用函数,lapply()函数,sapply()函数,tapply()函数,当然,另外还有几个成员,先掌握这几个点使用。
5.3.1.apply()函数
我们来看一下老大哥 apply()函数中的相关参数和使用方法,apply(X, MARGIN,FUN, ...)对于 apply()函数的相关参数,其使用方法相对比较简单。首先,对于参数 X 表示输入一个数组,自然也包括矩阵,参数 MARGIN 则表示是一个代表下标或者索引的向量,比如 说,对于矩阵和数据框,1 表示行,2 表示列,c(1,2)表示行和列,而参数 FUN,也就是 Function 的含义,表示对该矩阵进行的操作内容。接下来,我们先生成一个矩阵1 到 24,定义 4 行 6 列,然后,我们来使用 apply()函数对这个矩阵进行数据汇总
分析
首先,来算一下每一行的总和。
这里需要注意一点,在 FUN 部分,应该写 sum,而不是 sum(),当然,我们可以将 1 改成 2,表示求每列。
sum 也可以改成 mean,表示求平均数,或者 sd,求标准差那么数据框格式是否可以使用 apply()函数呢?用 iris 数据集试一下:
解释一下,由于 iris 数据集的第 5 列是因子型的数据内容,无法求均值,因此,我们通过 iris[,1:4]取前 4 列来求平均值。
5.3.2.lapply()函数
对于 lapply()函数,与 apply()函数的数据汇总功能类似,但是,它还另外多了一个功能,遍历,也就是说,对其中每一个元素进行浏览。
对 1 到 5 每个元素进行了 log 转换,而且,最终结果的格式为列表 list 格式这里也可以看到,这个列表由 5 个元素组成,如果要取第 2 个元素的话当然,我们也可以将数据框作为纳入数据,同时,我们对 FUN 函数进行自定义稍微复杂了一点,可以先看下,lm()函数表示构建线性模型,我们取其中第一个元
素出来看下:
表示取第一列的数据,与第四列 Petal.Width 的数据构建了 y=a+bx 的线性模型,而与 之相对应的另一个函数 sapply()函数,它的用法,与 lappy 函数基本类似,只是输出结果不同,sapply(1:3,function(x)x+3),对 1 到 3,每个元素加上 3,但是,它的输出结果是一个向量形式那么,如果用 sapply 来构建线性模型会怎样呢?
基本就是一串奇怪的数据框,没有什么可用信息。最后,还有一个函数的使用,和前面三个兄弟有一点点差别。对于 tapply()函数,其输入数据必须是数据框格式关于 tapply()函数的使用,简单来讲,就是根据一个分类变量,对一个数字型变量来进行数据汇总,还是使用 iris 数据集来进行演示。
在 X 中需要输入一个数值型变量,INDEX 中输入一个分类变量,后面紧跟一个函数,就是根据 INDEX 的不同水平,对 X 中的内容进行函数中的计算关于这四个函数的使用,可以直接根据代码(apply 函数.R)或者自己的数据来演示一下