Bootstrap

R语言实战 第二章(一)

R语言实战 第二章(一)

2.2 数据结构

2.2.1 向量

向量是用于存储数值型、字符型或逻辑型数据的一维数组。同一向量中无法混杂不同模式的数据。

a <- c(1, 2, 5, 3, 6, -2, 4)
b <- c("one", "two", "three")
c <- c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE)

注意 标量是只含一个元素的向量,例如f <- 3、g <- "US"和h <- TRUE。它们用于保存常量。

> a <- c("k", "j", "h", "a", "c", "m")
> a[3]
[1] "h"
> a[c(1, 3, 5)]
[1] "k" "h" "c"
> a[2:6]
[1] "j" "h" "a" "c" "m"

2.2.2 矩阵

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

myymatrix <- 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),默认情况下按列填充。

代码清单2-1 创建矩阵

> y <- matrix(1:20, nrow=5, ncol=4)
> 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(1,26,24,68)
> rnames <- c("R1","R2")
> cnames <- c("C1","C2")
> mymatrix <- matrix(cells, nrow=2, ncol=2, byrow=TRUE, dimnames=list(rnames,cnames))
> mymatrix
   C1 C2
R1  1 26
R2 24 68
> mymatrix <- matrix(cells, nrow=2, ncol=2, byrow=FALSE, dimnames=list(rnames,cnames))
> mymatrix
   C1 C2
R1  1 24
R2 26 68
> 

代码清单2-2 矩阵下标的使用

 x <- matrix(1:10, nrow=2)
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    3    5    7    9
[2,]    2    4    6    8   10
> x[2,]
[1]  2  4  6  8 10
> x[,2]
[1] 3 4
> x[1,4]
[1] 7
> x[1,c(4,5)]
[1] 7 9
> 

2.2.3 数组

数组(array)与矩阵类似,但是维度可以大于2。

myarray <- array(vector, dimensions, dimnames)

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

代码清单2-3 创建一个数组

> dim1 <- c("A1","A2")
> dim2 <- c("B1","B2","B3")
> dim3 <- c("C1","C2","C3","C4")
> z <- array(1:24, c(2,3,4), dimnames=list(dim1, dim2, dim3))
> z
, , C1

   B1 B2 B3
A1  1  3  5
A2  2  4  6

, , C2

   B1 B2 B3
A1  7  9 11
A2  8 10 12

, , C3

   B1 B2 B3
A1 13 15 17
A2 14 16 18

, , C4

   B1 B2 B3
A1 19 21 23
A2 20 22 24

> 

2.2.4 数据框

由于不同的列可以包含不同模式(数值型、字符型等)的数据,数据框的概念较矩阵来说更为一般。它与你通常在SAS、SPSS和Stata中看到的数据集类似。数据框将是你在R中最常处理的数据结构。

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

其中的列向量col1、col2、col3等可为任何类型(如字符型、数值型或逻辑型)。每一列的名称可由函数names指定。每一列数据的模式必须唯一,不过你却可以将多个模式的不同列放到一起组成数据框。

代码清单2-4 创建一个数据框

> 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
> 

代码清单2-5 选取数据框中的元素

> patientdata[1:2]
  patientID age
1         1  25
2         2  34
3         3  28
4         4  52
> patientdata[c("diabetes", "status")]
  diabetes    status
1    Type1      Poor
2    Type2  Improved
3    Type1 Excellent
4    Type1      Poor
# patientdata$age表示patientdata数据框中的变量age
> patientdata$age
[1] 25 34 28 52
# 如果你想生成糖尿病类型变量diabetes和病情变量status的列联表,使用以下代码即可:
> table(patientdata$diabetes, patientdata$status)
       
        Excellent Improved Poor
  Type1         1        0    2
  Type2         0        1    0
> 
  1. attach()、detach()和with()
    函数attach()可将数据框添加到R的搜索路径中。R在遇到一个变量名以后,将检查搜索路径中的数据框。以第1章中的mtcars数据框为例,可以使用以下代码获取每加仑行驶英里数(mpg)变量的描述性统计量,并分别绘制此变量与发动机排量(disp)和车身重量(wt)的散点图:
summary(mtcars$mpg)
plot(mtcars$mpg, mtcars$disp)
plot(mtcars$mpg, mtcars$wt)

以上代码也可写成:

attach(mtcars)
	summary(mpg)
	plot(mpg, disp)
	plot(mpg, wt)
detach(mtcars)

函数detach()将数据框从搜索路径中移除。值得注意的是,detach()并不会对数据框本身做任何处理。这句是可以省略的,但其实它应当被例行地放入代码中,因为这是一个好的编程习惯。当名称相同的对象不止一个时,这种方法的局限性就很明显了。考虑以下代码:

> mpg <- c(25, 36, 47)
> attach(mtcars)
The following object is masked _by_ .GlobalEnv:

    mpg

> plot(mpg, wt)
Error in xy.coords(x, y, xlabel, ylabel, log) : 'x''y'的长度不一样
> mpg
[1] 25 36 47
> 

这里,在数据框mtcars被绑定(attach)之前,你们的环境中已经有了一个名为mpg的对象。在这种情况下,原始对象将取得优先权,这与你们想要的结果有所出入。由于mpg中有3个元素而disp中有32个元素,故plot语句出错。函数attach()和detach()最好在你分析一个单独的数据框,并且不太可能有多个同名对象时使用。任何情况下,都要当心那些告知某个对象已被屏蔽(masked)的警告。除此之外,另一种方式是使用函数with()。可以这样重写上例:

> with(mtcars, {
+ print(summary(mpg))
+ plot(mpg, disp)
+ plot(mpg, wt)
+ })
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.40   15.43   19.20   20.09   22.80   33.90 
> 

在这种情况下,花括号{}之间的语句都针对数据框mtcars执行,这样就无需担心名称冲突了。如果仅有一条语句(例如summary(mpg)),那么花括号{}可以省略。函数with()的局限性在于,赋值仅在此函数的括号内生效。考虑以下代码:

> with(mtcars, {
+ stats <- summary(mpg)
+ stats
+ })
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.40   15.43   19.20   20.09   22.80   33.90 
> stats
错误: 找不到对象'stats'
> 

如果你需要创建在with()结构以外存在的对象,使用特殊赋值符<<-替代标准赋值符(<-)即可,它可将对象保存到with()之外的全局环境中。这一点可通过以下代码阐明:

> with(mtcars, {
+ nokeepstats <- summary(mpg)
+ keepstats <<- summary(mpg)
+ })
> nokeepstats
错误: 找不到对象'nokeepstats'
> keepstats
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.40   15.43   19.20   20.09   22.80   33.90 
> 
  1. 实例标识符
    在病例数据中,病人编号(patientID)用于区分数据集中不同的个体。在R中,实例标识符(case identifier)可通过数据框操作函数中的rowname选项指定。例如,语句:
> patientdata <- data.frame(patientID, age, diabetes, status, row.names=patientID)

将patientID指定为R中标记各类打印输出和图形中实例名称所用的变量。

2.2.5 因子

变量可归结为名义型、有序型或连续型变量。
名义型变量是没有顺序之分的类别变量。
有序型变量表示一种顺序关系,而非数量关系。
连续型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。
类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。
函数factor()以一个整数向量的形式存储类别值,整数的取值范围是[1…k](其中k是名义型变量中唯一值的个数),同时一个由字符串(原始值)组成的内部向量将映射到这些整数上。

diabetes <- factor(diabetes)

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

status <- factor(status, ordered=TRUE)

对于字符型向量,因子的水平默认依字母顺序创建。
按默认的字母顺序排序的因子很少能够让人满意,可以通过指定levels选项来覆盖默认排序。

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

数值型变量可以用levels和labels参数来编码成因子。

sex <- factor(sex, levels=c(1, 2), labels=c("Male", "Female"))

代码清单2-6 因子的使用

> # 以向量形式输入数据
> patientID <- c(1,2,3,4)
> > age <- c(25, 34, 28, 52)
> diabetes <- c("Type1", "Type2", "Type1", "Type1")
> status <- c("Poor", "Improved", "Excellent", "Poor")
> diabetes <- factor(diabetes)
> status <- factor(status, order=TRUE)
> patientdata <- data.frame(patientID, age, diabetes, status)
> # 显示对象的结构
> str(patientdata)
'data.frame':   4 obs. of  4 variables:
 $ patientID: num  1 2 3 4
 $ age      : num  25 34 28 52
 $ diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 1
 $ status   : Ord.factor w/ 3 levels "Excellent"<"Improved"<..: 3 2 1 3
> # 显示对象的统计概要
> summary(patientdata)
   patientID         age         diabetes       status 
 Min.   :1.00   Min.   :25.00   Type1:3   Excellent:1  
 1st Qu.:1.75   1st Qu.:27.25   Type2:1   Improved :1  
 Median :2.50   Median :31.00             Poor     :2  
 Mean   :2.50   Mean   :34.75                          
 3rd Qu.:3.25   3rd Qu.:38.50                          
 Max.   :4.00   Max.   :52.00                         

2.2.6 列表

列表(list)是R的数据类型中最为复杂的一种。一般来说,列表就是一些对象(或成分,component)的有序集合。列表允许你整合若干(可能无关的)对象到单个对象名下。例如,某个列表中可能是若干向量、矩阵、数据框,甚至其他列表的组合。

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

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

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

代码清单2-7 创建一个列表

> g <- "My First List"
> h <- c(25, 26, 18, 39)
> j <- matrix(1:10, nrow=5)
> k <- c("one", "two", "three")
> mylist <- list(title=g, ages=h, j, k)
> mylist
$title
[1] "My First List"

$ages
[1] 25 26 18 39

[[3]]
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8
[4,]    4    9
[5,]    5   10

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

> mylist[[2]]
[1] 25 26 18 39
> mylist[["ages"]]
[1] 25 26 18 39

你也可以通过在双重方括号中指明代表某个成分的数字或名称来访问列表中的元素。对于命名成分,mylist$ages也可以正常运行。由于两个原因,列表成为了R中的重要数据结构。首先,列表允许以一种简单的方式组织和重新调用不相干的信息。其次,许多R函数的运行结果都是以列表的形式返回的。

;