R语言基础教程1:数据类型
(2014-03-27 17:10:57)
标签:
教育 |
分类: R |
R语言是面向对象的。面向对象的理论一两句话说不清楚(我不清楚),但对于数据至少应该了解三个:
1、R能处理的东西(包括数据)都称为object。这个英文单词的意思原本很清楚,就是物体、物件的意思,但被计算机专家们翻译成“对象”以后就很玄乎了。
2、 物(object)以类聚。一个object都应该能找到它所归属的某个类(class)。“类”是抽象的概念,一个类至少有一个特征是这类数据所共有 的。根据应用需求、目的等不同可以定义不同的类。比如做生物信息的可以定义出DNA类、RNA类,为了高效处理这类数据,定义这些类是非常必要的。所以R 里面有很多的“类”。
3、类可以继承产生儿孙类。
我们不可能也没必要去了解所有的“类”,但R语言定义的一些基本数据类得了解,而且得较详细地了解。这包括向量、因子、矩阵、列表、数据框和一些特殊值数据。
一、向量(vector)
我们通常接触的数据主要是数字、字符和逻辑(真和假,是或不是)类型的。数据有一个个的,也有一串串一批批的。在R里面,最基本的数据类是向量,即一串有序数据;但vector是虚拟类,没有父类型,它包含了在其他语言里面常说的基本数据类型如整型、字符型和逻辑型等:
>getClass ("vector")
VirtualClass "vector" [package "methods"]
NoSlots, prototype classof "logical"
KnownSubclasses: #已知子类
Class"logical", directly
Class"numeric", directly
Class"character", directly
Class"complex", directly
Class"integer", directly
Class"raw", directly
Class"expression", directly
Class"list", directly
Class"structure", directly ,with explicit coerce
Class"array", by class "structure", distance 2,with explicit coerce
Class"matrix", by class "array", distance 3,with explicit coerce
Class"signature", by class "character", distance 2
Class"className", by class "character", distance 2
Class"ObjectsWithPackage", by class "character", distance 2
Class"mts", by class "matrix", distance 4,with explicit coerce
Class"ordered", by class "factor", distance 3
Class"namedList", by class "list", distance 2
Class"listOfMethods", by class "namedList", distance 3
R语言处理数据的最基本单位是向量,而不是原子数据。所以向量又称为原子向量(atomic vector),R语言的数据单位里面它最小(也最大,没有谁是它的父母)。但由于vector是虚拟类,不管用什么方式你都不可能获得类型名称叫“vector”的对象,只能获得它的直接子类的对象。下面的x是一个矩阵,虽然我们用as.vector函数进行转换,但获得对象的类名称是integer而不是vector:
> x <- matrix(1:4, nrow=2)
> class(x)
[1] "matrix"
> class(as.vector(x))
[1] "integer"
一个向量可以是一串数字(n个数字,向量长度为n),也可以是1个数字(向量长度为1):
>x =1:40
>x
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
[25]25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
>x =1
>x
[1]1
等于号可以用于向量赋值,但符号“<-”更常用,更好,更专业:
>x <-c (1,2,3)
>x
[1]1 2 3
>y <-c ("赵匡胤","钱学森", "孙思邈")
>y
[1]"赵匡胤" "钱学森" "孙思邈"
c(
>class(x)
[1]"numeric"
>class(y)
[1]"character"
一个向量只属于一种类型,如果改变了一个元素的值可能会改变该向量的类型:
>x <-seq (10)
>x
[1]1 2 3 4 5 6 7 8 9 10
>class(x)
[1]"integer"
>x [2]<- "Adam"
>x
[1]"1" "Adam" "3" "4" "5" "6" "7" "8" "9" "10"
>class(x)
[1]"character"
向量元素的引用/提取用下标法如
二、因子(factor)
R定义了一类非常特殊的数据类型:因子。比如我们的实验获得了10个数据,前5个数据来自对照样品CK,其余属于处理样品TR,R语言中可以用下面方法标识这10个数据的样品属性:
>sample <-rep (c("CK","TR"),each =5)
>sample<- factor (sample)
>sample
[1] CK CK CK CK CK TR TR TR TR TR
Levels:CK TR
因子的种类称为水平(level)。上面的样品sample因子有两个水平:CK和TR。因子类数据很特殊:
>getClass ("factor")
Class"factor" [package "methods"]
Slots:
Name:.Data .S3Class levels
Class:integer character character
Extends:
Class"integer", from data part
Class"oldClass", directly
Class"numeric", by class "integer", distance 2
Class"vector", by class "integer", distance 2
KnownSubclasses: "ordered"
使用因子类数据是因为R是针对统计应用的语言。使用因子以后,数据的统计会完全不同。比如上面的两个样品10个测定数值如果是:
>value <-rnorm (10)
>value
[1] 1.44368380 -1.99417898 0.60279037 0.75186610 1.08372729 -0.16189030
[7] -0.05617801 1.03601538 -0.87932814 -0.32429184
求样品的平均值就可以这么做:
>tapply (value,sample ,mean )
CK TR
0.37757771 -0.07713458
gl(
>sample <-gl (2,5, labels =c ("CK","TR"))
>sample
[1] CK CK CK CK CK TR TR TR TR TR
Levels:CK TR
三、矩阵(matrix)
矩阵的继承关系比较复杂,它和数组(array)的关系既是父亲又是儿子,还是孙子:
>getClass ("matrix")
Class"matrix" [package "methods"]
NoSlots, prototype classof "matrix"
Extends:
Class"array", directly
Class"structure", by class "array", distance 2
Class"vector", by class "array", distance 3,with explicit coerce
KnownSubclasses:
Class"array", directly ,with explicit test andcoerce
Class"mts", directly
如果你愿意,也可以把矩阵称为数组,但事实上它们是不同的类。生物类数据以二维数组/矩阵居多。
向量数据可以转成矩阵,下面代码将10个元素的x转成2行5列的矩阵:
>x <-1:10
>dim (x)<- c (2,5)
>x
[,1] [,2] [,3] [,4] [,5]
[1,]1 3 5 7 9
[2,]2 4 6 8 10
>dim (x)
[1]2 5
dim(
>x [2,1]
[1]2
>x [2,]
[1]2 4 6 8 10
>x [,2]
[1]3 4
把1个向量转成矩阵还可以使用matrix(
>matrix (1:10,nrow =2)
[,1] [,2] [,3] [,4] [,5]
[1,]1 3 5 7 9
[2,]2 4 6 8 10
几个长度相同的向量也可以合并到一个矩阵,cbind(
>x <-3:6
>y <-4:7
>z <-1:4
>cbind (x,y,z)
x y z
[1,]3 4 1
[2,]4 5 2
[3,]5 6 3
[4,]6 7 4
>rbind (x,y,z)
[,1] [,2] [,3] [,4]
x3 4 5 6
y4 5 6 7
z1 2 3 4
不同向量的数据类型要相同,否则转换成矩阵后数据类型会变样。下面代码将height内的数字全都转成了字符类型,这可能不是你想要的结果:
>name <-c ("赵匡胤","钱学森", "孙思邈")
>height <-c (172,175, 168)
>info <-rbind (name,height)
>info
[,1] [,2] [,3]
name"赵匡胤" "钱学森" "孙思邈"
height"172" "175" "168"
>class(info)
[1]"matrix"
身高是数值,但跟姓名混合组成矩阵后就变成字符型了(输出结果中用双引号引起来)。
矩阵元素可通过下标引用,多维矩阵可以只用一个下标,请注意info[3]获得的数据:
>info [1,]
[1]"赵匡胤" "钱学森" "孙思邈"
>info [,1]
name height
"赵匡胤""172"
>info [3]
[1]"钱学森"
四、列表(list)
列表由向量直接派生而来,nameList是它的子类,listOfMethods是它家孙子:
>getClass ("list")
Class"list" [package "methods"]
NoSlots, prototype classof "list"
Extends:"vector"
KnownSubclasses:
Class"namedList", from data part
Class"listOfMethods", by class "namedList", distance 2
那么列表是什么样子的呢?看这:
>gene <-list (agi="AT1G00010",gene .mode=c("AT1G00010.1","AT1G00010.2", "AT1G00010.3"), expression =matrix(1:10,ncol =2))
>gene
$agi
[1]"AT1G00010"
$gene.mode
[1]"AT1G00010.1" "AT1G00010.2" "AT1G00010.3"
$expression
[,1] [,2]
[1,]1 6
[2,]2 7
[3,]3 8
[4,]4 9
[5,]5 10
列表可以组合不同的数据类型,甚至可以是其他列表,各组成数据的类、长度、维数都可以不一样。
五、数据框(data
R
语言中,一个矩阵内的数据类型要求都要相同,这对生物类数据不大适用,因为我们的数据经常是既有数字又有字符类标记。R语言提供了另外一种更灵活的数据类
型:数据框。可以将几个不同类型但长度相同的向量用data.frame(
>name <-c ("赵匡胤","钱学森", "孙思邈")
>height <-c (172,175, 168)
>info <-data .frame(name,height)
>info
name height
1赵匡胤 172
2钱学森 175
3孙思邈 168
用as.data.frame(
虽然数据框的外观和二维矩阵差不多,但它却不是从矩阵而是从列表派生来的,它是数据(.data)是列表数据,列名称(names)就是列表中各项的名称,另外还有行名称(row.names):
>getClass ("data.frame")
Class"data.frame" [package "methods"]
Slots:
Name:.Data .names names row
Class:.frameRowLabels list character data
Name:.S3Class
Class:character
Extends:
Class"list", from data part
Class"oldClass", directly
Class"data.frameOrNULL", directly
Class"vector", by class "list", distance 2
数据框的每列是一个向量,称为列向量。列向量只有两种类型,要么是数字型,要么是因子型。从文件读取或其他类型数据转换成数据框的数据,如果不是数值型,会被强制转换成因子型。有时候数值型(尤其是整型)向量也会被转成因子,这点应该注意。
数据框可以用数字下标取数据,也可以用列名称下标取数据,但是两种方式所获数据的类型是不一样的,按列名称下标方式取得的数据仍然是数据框:
>info [,1]
[1]赵匡胤 钱学森 孙思邈
Levels:钱学森 孙思邈 赵匡胤
>class(info[,1])
[1]"factor"
>info ["name"]
name
1赵匡胤
2钱学森
3孙思邈
>class(info["name"])
[1]"data.frame"
为什么要注意这个区别?因为看起来像是同样的数据,在一些对类型要求很严格的操作(比如作图)中得到完全不一样的结果。数据框还有一种数据提取方式,得到因子或向量:
>class(info$name)
[1]"factor"
>class(info$height)
[1]"numeric"
六、特殊值数据
为确保所有数据都能被正确识别、计算或统计等,R定义了一些特殊值数据:
NULL:空数据
NA:表示无数据
NaN:表示非数字
inf:数字除以0得到的值
判断一个object
is.null(x)
is.na(x)
is.nan(x)
is.infinite(x)
七、获取数据类型信息的一些有用函数
R语言的对象“类”很多,虽然我们不可能一一去详细学习,但接触到一类新数据时我们需要了解一些基本信息才能进行进一步的操作。R提供了一些非常有用的方法(函数)。
getClass(
class(
str(
mode(
typeof(