vlambda博客
学习文章列表

R语言入门(2)——创建数据集


因为疫情,学校迟迟没有开学,再加上自身实验数据的产出十分依赖于生信分析,所以目前计划以“R语言实战 第二版”为指南,学习一下基础的生信分析,以下为学习记录。

 

本篇主要内容为介绍R语言中的各种数据类型,包括标量、向量、矩阵(matrix)、数组(array)、数据框(data.frame)和列表(list)。


  • 概述

数据集通常是由数据构成的一个矩形数组,行表示观测,列表示变量。


如下图,提供了一个假想的病例数据集。

行表示观测(observation),列表示变量(variable)

其中:PatientID是行/实例标识符,AdmDate是日期型变量,Age是连续型变量,Diabetes是名义型变量,Status是有序型变量。


 

  • 数据结构

R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表。


  1. 标量

    标量是只含一个元素的向量,

    例如f <- 3g <- "US" h <- TRUE。它们用于保存常量。



  2. 向量

    向量是用于存储数值型、字符型或逻辑型数据的一维数组。执行组合功能的函数c( )可用来 创建向量。各类向量如下例所示:

    a <- c(1, 2, 5, 3, 6, -2, 4)                              数值型向量

    b <- c("one", "two", "three")                            字符型向量

    c <- c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE)    逻辑型向量

    注意:单个向量中的数据必须拥有相同的类型或模式(数值型、字符型或逻辑型)。同一向量中无法混杂不同模式的数据。



    通过在方括号中给定元素所处位置的数值,我们可以访问向量中的元素。如,a[c(2, 4)] 用于访问向量a中的第二个和第四个元素。更多示例详见代码2-1

    代码2-1  创建向量、方括号使用实例

    > a <- c("k","j", "h", "a", "c", "m")        给向量a赋值

    > a[3]                                                   访问向量a中第3个元素

    [1] "h"

    > a[c(1, 3, 5)]                                        访问向量a中第1、3、5个元素

    [1] "k" "h" "c"

    > a[2:6]                                                 访问向量a中第2到6个元素

    [1] "j""h" "a" "c" "m"



  3. 矩阵(matrix)

    矩阵是一个二维数组,只是每个元素都拥有相同的模式(数值型、字符型或逻辑型,可通过函数matrix( )创建矩阵。


    mymatrix <- matrix(vector, nrow=number_of_rows,ncol=number_of_columns, byrow=logical_value, dimnames=list(char_vector_rownames,char_vector_colnames))

    vector包含了矩阵的元素,nrow和ncol用以指定行和列的维数,dimnames包含了可选的、以字符型向量表示的行名和列名,byrow则表明矩阵应当按行填充(byrow=TRUE)/按列填充(byrow=FALSE),默认按列填充。


  4.  

    我们可以使用下标方括号来选择矩阵中的行、列或元素。X[i,]指矩阵X中的第i行,X[,j] 指第j列,X[i, j]指第i行第j 个元素。选择多行或多列时,下标i和j可为数值型向量,如代码2-2所示。


    代码2-2    创建矩阵——函数matrix( )的使用方法 

    > y<- matrix(1:20,nrow=5,ncol=4)                 给矩阵y赋值:元素为1到20,5行,4列

    > y                                                                   输出矩阵y的值

        [,1] [,2] [,3] [,4]

    [1,]   1    6   11  16

    [2,]   2    7   12  17

    [3,]   3    8   13  18

    [4,]   4    9   14  19

    [5,]   5   10   15  20

    > cells<-c(10,20,30,40)                     给向量cells赋值:元素为10,20,30,40

    >rnames<-c("R1","R2")                                   给矩阵中的行的分别命名为“R1”,“R2”

    >cnames<-c("C1","C2")                                   给矩阵中的列的分别命名为“C1”,“C2”

    > mymatrix<-matrix(cells,nrow=2,ncol=2,byrow=TRUE,dimnames=list(rnames,cnames))                                                       给矩阵mymatrix赋值:元素为cells中的内容,2行,2列,按行排列,行列命名分别按照rname,cname中的字符命名。

    > mymatrix                                                      输出矩阵mymatrix的值

       C1C2

    R1 10 20

    R2 30 40

    >mymatrix<-matrix(cells,nrow=2,ncol=2,byrow=FALSE,dimnames=list(rnames,cnames))                                                       给矩阵mymatrix赋值:元素为cells中的内容,2行,2列,按列排列,行列命名分别按照rname,cname中的字符命名。

    > mymatrix                                                      输出矩阵mymatrix的值

       C1C2

    R1 10 30

    R2 20 40

    > mymatrix[1,2]                           访问矩阵mymatrix中第1行第二列的元素

    [1] 30


    代码2-3    矩阵下标的使用方法

    > x<-matrix(1:10,nrow=5)                 给矩阵x赋值:元素为1到10,5行

    > x                                                                 输出矩阵x的值

        [,1] [,2]

    [1,]   1    6

    [2,]    2    7

    [3,]   3    8

    [4,]   4    9

    [5,]   5   10

    > x[2,]                                    访问矩阵x中第2行的元素

    [1] 2 7

    > x[c(2:4),2]                             访问矩阵x中第2到4行中,第二列的元素

    [1] 7 8 9

     

    矩阵都是二维的,和向量类似,矩阵中也仅能包含一种数据类型。当维度超过2时,不妨使用数组(第4节)。当有多种模式的数据时,可以使用数据框(第5节)。


  5. 数组(array)

    数组(array)与矩阵类似,但是维度可以大于2。数组可通过array函数创建,形式如下:



        myarray <- array(vector,dimensions, dimnames) 


  6. vector包含了数组中的数据,dimensions是一个数值型向量,给出了各个维度下标的大值,dimnames是可选的、各维度名称标签的列表。


    代码2-4    创建三维(2x3x4数值型数组)的实例演示

    > dim1<-c("A1","A2")                                          给第一维dim1(行)命名为A1,A2

    >dim2<-c("B1","B2","B3")                                    给第二维dim2(列)命名为B1,B2,B3

    >dim3<-c("C1","C2","C3","C4")                            给第三维dim3(表)命名为C1,C2 ,C3, C4

    > z<- array(1:24, c(2,3,4),dimnames=list(dim1,dim2,dim3))                                                                                                                            给数组z赋值:包含从1到24的数据,三个维度分别有2、3、4个值,每个维度命名按照dim1,dim2,dim3命名


    > z                                                                         输出数组z的值

    , , C1

     

       B1B2 B3

    A1 1  3  5

    A2 2  4  6

     

    , , C2

     

       B1B2 B3

    A1 7  9 11

    A2  810 12

     

    , , C3

     

       B1B2 B3

    A1 13 15 17

    A2 14 16 18

     

    , , C4

     

       B1B2 B3

    A1 19 21 23

    A2 20 22 24

     

    > z[2,2,3]                                                                 访问数组z中第3张表中第2行第2列的值

    [1] 16

     

    数据框(data.frame)

    由于数据有多种模式,无法将包含不同模式(字符型、数值型、逻辑型)的数据放入一个矩阵。在这种情况下,使用数据框是最佳选择。

    数据框可通过函数data.frame()创建:

     

    mydata <- data.frame(col1,col2, col3,...)

    列向量col1、col2、col3等可为任何类型(如字符型、数值型或逻辑型),每一列的名称可由函数names指定。


    代码2-5  创建一个数据框

    > patientID<-c("Allen","Bell","Cassile","Eva")    给向量patienID赋值

    > age<-c(25,24,23,22)                                  给向量age赋值

    >diabetes<-c("Type1","Type2","Type1","Type1")    给向量diabetes赋值

    > status<-c("poor","improved","excellent","poor")给向量status赋值

    >patientdata<-data.frame(patientID,age,diabetes,status)给数据框patientdata赋值:第一列为patientID,第二列为age,第三列为diabetes,第四列为status

    > patientdata                                            输出patientdata的值

     patientID age diabetes    status

    1    Allen  25    Type1     poor

    2     Bell  24    Type2 improved

    3  Cassile  23    Type1 excellent

    4      Eva  22    Type1     poor

    > patientdata[2,3]                     访问数据框patientdata中第二行第三列的值

    [1] Type2

    Levels: Type1 Type2

    > patientdata[2,]                      访问数据框patientdata中第二行的值

     patientID age diabetes   status

    2     Bell  24    Type2 improved

    > patientdata$patientID               $展示给定数据框(patientdata)中的某个特定变量(patientID)

    [1] Allen  Bell    Cassile Eva   

    Levels: Allen Bell Cassile Eva

    >table(patientdata$age,patientdata$status)           生成两个变量(age&status)的列联表


                   excellent improved poor

              22         0        0   1

              23         1        0   0

              24         0        1   0

              25         0        0   1


    在病例数据中,病人编号(patientID)用于区分数据集中不同的个体。在R中,实例标识符(case identifier)可通过数据框操作函数中的rowname选项指定。


    代码2-6  实例标识符的使用

    >patientdata<-data.frame(patientID,age,diabetes,status,row.names =patientID)           

                                                                 指定patientID为实例标识符

    > patientdata                                                         输出指定实例标识符后的数据框patientdata

           patientID age diabetes    status

    Allen      Allen  25    Type1     poor

    Bell        Bell  24    Type2 improved

    Cassile  Cassile  23    Type1 excellent

    Eva          Eva  22    Type1     poor



    变量可归结为名义型有序型连续型变量

    名义型变量是没有顺序之分的类别变量。如糖尿病类型Diabetes(Type1、Type2)是名义型变量的一例。即使在数据中Type1编码为1而Type2编码为2,但并不意味着二者是有序的。

    有序型变量表示一种顺序关系,而非数量关系。病情Status(poor、improved、excellent)是顺序型变量的一个上佳示例。我们知道,病情为poor(较差)病人的状态不如improved(病情好转)的病人,但并不知道相差多少。

    连续型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。年龄Age就是一个连续型变量,它能够表示像14.5或22.8这样的值以及其间的其他任意值。我们很清楚,15岁的人比14岁的人年长一岁。

    类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。因子在R中非常重要,因为它决定了数据的分析方式以及如何进行视觉呈现。

    函数factor( )以一个整数向量的形式存储类别值,整数的取值范围是[1...k](其中k是名义型变量中唯一值的个数),同时一个由字符串(原始值)组成的内部向量将映射到这些整数上。举例来说,假设有向量:

     

    diabetes <- c("Type1","Type2", "Type1", "Type1")

    语句diabetes<- factor(diabetes)将此向量存储为(1, 2, 1, 1),并在内部将其关联为 1=Type1和2=Type2(具体赋值根据字母顺序而定)。针对向量diabetes进行的任何分析都会将其作为名义型变量对待,并自动选择适合这一测量尺度的统计方法。


    要表示有序型变量,需要为函数factor( )指定参数ordered=TRUE。给定向量:

     

    status <-c("Poor", "Improved", "Excellent","Poor")

    语句status<- factor(status, ordered=TRUE)会将向量编码为(3, 2, 1, 3),并在内部将这些值关联为1=Excellent、2=Improved以及3=Poor另外,针对此向量进行的任何分析都会将其作为有序型变量对待,并自动选择合适的统计方法。


    对于字符型向量,因子的水平默认依字母顺序创建。这对于因子status是有意义的,因为“Excellent”“Improved”“Poor”的排序方式恰好与逻辑顺序相一致。如果“Poor”被编码为 “Ailing”,会有问题,因为顺序将为“Ailing”“Excellent”“Improved”。如果理想中的顺序是 “Poor” “Improved” “Excellent”,则会出现类似的问题。按默认的字母顺序排序的因子很少能够让人满意。

     你可以通过指定levels选项来覆盖默认排序。例如:

     

    status <- factor(status,order=TRUE, levels=c("Poor", "Improved","Excellent"))

    各水平的赋值将为1=Poor、2=Improved、3=Excellent。


    请保证指定的水平与数据中的真实值相匹配,因为任何在数据中出现而未在参数中列举的数据都将被设为缺失值。


    代码2-7   各类因子的差别

    >patientID<-c("Allen","Bell","Cassile","Eva")

    > age<-c(25,24,23,22)

    >diabetes<-c("Type1","Type2","Type1","Type1")

    >status<-c("poor","improved","excellent","poor")                                                      输入数据

    > status <- factor(status,order=TRUE)                                                     将status设为有序因子

    >patientdata<-data.frame(patientID,age,diabetes,status)                     生成数据框patientdata


    > str(patientdata)                         str(object)可提供R中某个对象(本例中为数据框)的信息

    'data.frame':  4obs. of  4 variables:

     $patientID: Factor w/ 4 levels "Allen","Bell",..: 1 2 3 4

     $age      : num  25 24 23 22

     $diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 1

     $status   : Ord.factor w/ 3 levels"excellent"<"improved"<..: 3 2 1 3


    可以观察到,patientID/diabetes为普通因子,status为有序因子


    > summary(patientdata)                                                                      summary函数显示对象的统计学概要:数值型函数显示最小值、最大值、均值和各四分位数值;类别型变量则显示它对应的频数

      patientID      age         diabetes       status

     Allen :1   Min.   :22.00  Type1:3   excellent:1 

     Bell  :1   1st Qu.:22.75   Type2:1  improved :1 

     Cassile:1  Median :23.50            poor     :2 

     Eva   :1   Mean   :23.50                         

                3rd Qu.:24.25                         

                Max.   :25.00      


     

  7. 列表(list)

    某个列表中可能是若干向量、矩阵、数据框,甚至其他列表的组合。可以使用函数list( )创建列表:


    mylist <- list(object1, object2, ...) 

    其中的对象可以是目前为止讲到的任何结构。你还可以为列表中的对象命名:


    mylist <- list(name1=object1, name2=object2, ...)


    代码2-8   创建一个列表

    > g<-"My First List"

    > h<-c(25,26,18,39)

    > j<-matrix(1:8,nrow=2)

    > k<-c("one","two","three")

    >mylist<-list(title=g,age=h,j,number=k)                                                                                                               创建一个列表mylist:其中包含标量、向量、矩阵

    > mylist                          输出mylist的值

    $title

    [1] "My First List"

     

    $age

    [1] 25 26 18 39

     

    [[3]]

        [,1] [,2] [,3] [,4]

    [1,]   1    3    5   7

    [2,]   2    4    6   8

     

    $number

    [1] "one"   "two"   "three"

     

    > mylist[[1]]                               输出mylist中第一个成分的值

    [1] "My First List"

    > mylist[["number"]]                   输出mylist中number包含的值

    [1] "one"   "two"   "three"



 



如有错误烦请指正,如有侵权烦请告知。谢谢