第2章 R编程入门(一):数据集
2.1 R语言
R是一种解释性语言,输入后可直接给出结果。
R功能烤函数实现,函数形式如下:函数(输入数据, 参数=)
。
如果没有指定,则参数以默认值为准。
每一个函数执行特定的功能,后面紧跟括号,如:平均值mean()
、求和sum()
、绘图plot()
、排序sort()
。
R的函数又分为“高级”和“低级”函数,高级函数可调用低级函数。
“高级“函数习惯上称为泛型函数。
2.1.1 数据集的概念
在R中,穿件数据集包括以下两步:
- 选择一种数据结构来存储数据
- 将数据输入或导入这个数据结构中
数据集通常是由数据构成的一个矩形数组:
- 行:观测(observation)、记录(record)、示例(example)
- 列:变量(variable)、字段(field)、属性(attribute)
R可以处理的数据类型:
- 数值型(numeric)
> a <- -1
> is.numeric(a) # 判断a是否为数值型
[1] TRUE
- 字符型(character)
> b <- "peter"
> nchar(b) # 输出字符串的长度
[1] 5
-
日期型(date)
- 常用的日期型数据类型是
Date
(仅存储日期)和POSIXct
(同时存储日期和时间) - 处理日期型数据时,往往需要
as.Date()
函数或as.POSIXct()
函数将读入的数值型转换成日期型 - 使用
as.numeric()
函数或as.integer()
函数将日期型数据转换成数值型 -
strftime(x, format = "")
函数可以定义日期型数据的格式
- 常用的日期型数据类型是
> t <- as.Date("2020-10-09")
> class(t) # 输出t的数据类型
[1] "Date"
> ct <- as.POSIXct("2020-10-10 18:32:45")
> class(ct) # 输出ct的数据类型
[1] "POSIXct" "POSIXt"
> c_year <- as.integer(strftime(t,"%Y")) # 输出年份
> c_month <- as.integer(strftime(t,"%m")) # 输出月份
> c_week <- as.integer(strftime(t,"%W")) # 输出周数
> c_year;c_month;c_week
[1] 2020
[1] 10
[1] 40
-
逻辑型(logical):
TRUE
,FALSE
- 复数型
- 因子型(factor):表示不同的类别。因子是名义型变量或有序型变量
R中用于存储数据的结构:
-
标量:只含有一个元素的向量,如
f<-3
、g<-"US"
和h<-TRUE
,用于保存常量。 -
向量:用于存储
数值型
、字符型
或逻辑型
数据的一维数组 - 数组:
- 数据框:R中用于存储数据集的一种主要数据结构:列表示变量,行表示观测。
- 列表
(1)向量(vector)
- 一系列元素的组合,用于存储
数值型
、字符型
或逻辑型
数据的一维数组 - 执行组合功能的函数
c()
可以用来创建向量。
# 数值型向量
a <- c(1, 2, 3, 4, -9, -20)
# 字符型向量
b <- c("a", "b", "c", "b", "a")
c <- c("one", "china", "USA")
# 逻辑型向量
d <- c(TRUE, FALSE, FALSE, TRUE, TRUE)
- 单个向量中的数据必须拥有相同的类型或模式(数值型、字符型或逻辑型),同一向量中无法混杂不同模式的数据。
- 可以通过方括号
[]
中给定元素的索引(index)来访问向量中的元素。- 整数型索引:索引是元素的位置;
- 字符型索引:索引是名称属性;
- 逻辑型索引:索引的是相同长度的逻辑向量对应的逻辑值为真的元素
- 可以通过冒号
:
生成一个数值序列。
> d <- c(1, 3, 5, 6, 7, 10, 21, 17)
> d[2] # 取第2个元素
[1] 3
> d[-2] # 删除第2个元素
[1] 1 5 6 7 10 21 17
> d[c(1,4)] # 取第1个和第4个元素
[1] 1 6
> d[2:5] # d[2:5]等价于d[c(2:5)],取第2-5号元素
[1] 3, 5, 6. 7
> d[d>2] # 取大于2的元素
[1] 3 5 6 7 10 21 17
> d[d==1] # 取等于1的元素
[1] 1
> d[d<=5] # 取小于等于5的元素
[1] 1 3 5
(2)矩阵(matrix)
- 二维数组
- 每个元素都拥有相同的模式(数值型、字符型或逻辑型)
- 可以通过
matrix()
函数创建矩阵
matrix <- matrix ( vector, nrow=, ncol=, byrow=, dimnames=list() )
vector
包含了矩阵的元素;
nrow
和ncol
用以指定行和列的维数
dimnames
包含了可选的、以字符型向量表示的行名和列名
byrow
用以指明矩阵应当按行填充(byrow = TRUE
)还是按列填充(byrow = FALSE
),默认情况下按列填充
- 可以使用下标和方括号来选择矩阵中的行,列或者元素。
X[i,]
指矩阵X
中的第i
行
X[,j]
指矩阵X
中的第j
列
X[i, j]
指第i
行第j
个元素
选择多行或者多列时,下标i
和j
可以是数值型向量。
# 创建一个4行5列的矩阵
> x = matrix(21:40,nrow = 4, ncol = 5, byrow = FALSE)
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 21 25 29 33 37
[2,] 22 26 30 34 38
[3,] 23 27 31 35 39
[4,] 24 28 32 36 40
# 创建一个2行3列,含有行列标签,按行填充的矩阵
> fourcell = c(1,2,3,10,20,30)
> rnames = c("R1","R2")
> cnames = c("C1","C2", "C3")
> matrix = matrix(fourcell, nrow = 2, ncol = 3, byrow = TRUE, dimnames = list(rnames, cnames))
> matrix
C1 C2 C3
R1 1 2 3
R2 10 20 30
# 创建一个2行3列,含有行列标签,按列填充的矩阵
> matrix = matrix(fourcell, nrow = 2, ncol = 3, byrow = FALSE, dimnames = list(rnames, cnames))
> matrix
C1 C2 C3
R1 1 3 20
R2 2 10 30
# 创建一个内容为数字1~20的5行的矩阵,默认情况下案列填充
> aa = matrix(1:20, nrow=5)
> aa
[,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
# 选择第3行的元素
> aa[3,]
[1] 3 8 13 18
# 选择第3列的元素
> aa[,3]
[1] 11 12 13 14 15
# 选择第3行第3列的原色
> aa[3,3]
[1] 13
# 选择第3行第3、第4列的元素
> aa[3,c(3,4)]
[1] 13 18
# 原则第3列和第4列的元素
> aa[,c(3,4)]
[,1] [,2]
[1,] 11 16
[2,] 12 17
[3,] 13 18
[4,] 14 19
[5,] 15 20
(3)数组(array)
- 与矩阵类似,但是维度可以大于2
- 可以通过
array()
函数创建
array <- array ( vector, dimensions, dimnames )
vector
, 包含了数组中的数据;
dimensions
, 数值型向量,给出各维度下标的最大值
dimnames
, 可选的,各维度名称标签的列表
- 数组中的数据也只能拥有一种模式
- 从数组中取元素的方式与矩阵相同
> dim1 <- c("X1", "X2")
> dim2 <- c("Y1", "Y2", "Y3")
> dim3 <- c("Z1", "Z2", "Z3", "Z4")
> xyz <- array(1:24, c(2, 3, 4), dimnames=list(dim1, dim2, dim3))
> xyz
, , Z1
Y1 Y2 Y3
X1 1 3 5
X2 2 4 6
, , Z2
Y1 Y2 Y3
X1 7 9 11
X2 8 10 12
, , Z3
Y1 Y2 Y3
X1 13 15 17
X2 14 16 18
, , Z4
Y1 Y2 Y3
X1 19 21 23
X2 20 22 24
> xyz[1,2,]
Z1 Z2 Z3 Z4
3 9 15 21
> xyz[1,3,]
Z1 Z2 Z3 Z4
5 11 17 23
> xyz[,2,2]
X1 X2
9 10
> xyz[2,,4]
Y1 Y2 Y3
20 22 24
> xyz[1,2,3]
[1] 15
(4)数据框(data.frame)
- 与通常在SAS、SPSS和STATA中看到的数据集类似,不同的列可以包含不同模式的数据(数值型、字符型等)
- 数据框可以通过
data.frame()
创建
mydata = data.frame(col1, col2, col3, ···)
列向量
col1
,col2
,col3
……可为任何类型(如字符型、数值型或者逻辑型)。
每一列数据的模式必须唯一,但是不同列的数据模式可以不同。
每一列的名称可由函数names(df) <- c(col1_name, col2_name, col3_name, ...)
设定。
每一行的实例标识符
(case identifier)可以通过参数row.names =
指定,或者通过函数rownames(df) <- c()
设定。
> IDnumber <- c(101, 102, 103, 104)
> age <- c(24, 78, 56, 45)
> hypertention <- c("yes","no", "no", "yes")
> severity <- c("high", "middle", "low", "middle")
> patientdata <- data.frame(IDnumber, age, hypertention, severity)
> patientdata
IDnumber age hypertention severity
1 101 24 yes high
2 102 78 no middle
3 103 56 no low
4 104 45 yes middle
> patientdata <- data.frame(IDnumber, age, hypertention, severity, row.names = IDnumber)
> patientdata
IDnumber age hypertention severity
101 101 24 yes high
102 102 78 no middle
103 103 56 no low
104 104 45 yes middle
> rownames(patientdata) <- c("patient1", "patient2", "patient3", "patient4")
> patientdata
IDnumber age hypertention severity
patient1 101 24 yes high
patient2 102 78 no middle
patient3 103 56 no low
patient4 104 45 yes middle
> names(patientdata) <- c("ID", "Nianling", "yes or no", "Yanzhongxing")
> patientdata
ID Nianling yes or no Yanzhongxing
patient1 101 24 yes high
patient2 102 78 no middle
patient3 103 56 no low
patient4 104 45 yes middle
- 数据框中元素的获取方式,可以使用下标记号,也可以直接指定列名
- 也可以使用双方括号
[[列序号]]
或[[列名称]]
-
$
可以选取一个给定数据框中的某个特定变量,数据框名称$变量名称(列名称)
# 读取第1列元素
> patientdata[1]
IDnumber
1 101
2 102
3 103
# 读取第1列的元素
> patientdata[,1] # 等价于patientdata[[1]]
[1] 101 102 103 104
> patientdata[[1]]
[1] 101 102 103 104
> patientdata[["IDnumber"]]
[1] 101 102 103 104
# 读取第2行元素
> patientdata[2,]
IDnumber age hypertention severity
2 102 78 no middle
# 读取第2到第4行的元素
> patientdata[2:4,]
IDnumber age hypertention severity
2 102 78 no middle
3 103 56 no low
4 104 45 yes middle
# 读取第1到3列的元素
> patientdata[1:3] # 等价于 patientdata[,1:3]
IDnumber age hypertention
1 101 24 yes
2 102 78 no
3 103 56 no
4 104 45 yes
# 第2行第4列的元素
> patientdata[2,4]
[1] "middle"
# 读取“age”列的元素
> patientdata["age"]
age
1 24
2 78
3 56
4 45
> patientdata[["age"]]
[1] 24 78 56 45
# 读取“age”列和“severity”列的元素
> patientdata[c("age","severity")]
age severity
1 24 high
2 78 middle
3 56 low
4 45 middle
# 获取age变量的数据
> patientdata$age
[1] 24 78 56 45
- 获取数据框的行数、列数和维数:
nrow()
、ncol()
、dim()
。 - 获取数据框的列名或行名:
names()
、colnames()
、rownames()
。也可以重新定义列名names(df) <- c(col1_name, col2_name, col3_name, ...)
- 观察数据框的内容:
View(df)
、head(df, n=3)
、tail(df, n=1)
。
> nrow(patientdata) # 行数
[1] 4
> ncol(patientdata) # 列数
[1] 4
> dim(patientdata) # 维数
[1] 4 4
> names(patientdata) # 列名
[1] "IDnumber" "age" "hypertention" "severity"
> rownames(patientdata) # 行名
[1] "1" "2" "3" "4"
> colnames(patientdata) # 列名
[1] "IDnumber" "age" "hypertention" "severity"
> head(patientdata,n=3)
IDnumber age hypertention severity
1 101 24 yes high
2 102 78 no middle
3 103 56 no low
> tail(patientdata)
IDnumber age hypertention severity
1 101 24 yes high
2 102 78 no middle
3 103 56 no low
4 104 45 yes middle
> tail(patientdata,n=1)
IDnumber age hypertention severity
4 104 45 yes middle
attach()
和detach()
函数
-
attach()
可以将数据框添加到R
的搜索路径中。R
在遇到一个变量名以后,将检查搜索路径中的数据框,以定位到这个变量。 -
detach()
将数据框从搜索路径中移除,detach()
并不会对数据框本身做任何处理。 - 最好在分析一个单独的数据框,并且不太可能有多个同名对象时使用。
# 创建一个数据框
> systolic <- c(120,130,140,150,160)
> age <- c(20,30, 40, 50, 55)
> hypertension <- data.frame(systolic, age)
> hypertension
systolic age
1 120 20
2 130 30
3 140 40
4 150 50
5 160 55
> summary(hypertension$systolic)
Min. 1st Qu. Median Mean 3rd Qu. Max.
120 130 140 140 150 160
> summary(hypertension$age)
Min. 1st Qu. Median Mean 3rd Qu. Max.
20 30 40 39 50 55
> plot(hypertension$systolic, hypertension$age)
上述代码也可以写成:
> attach(hypertension)
> summary(age)
Min. 1st Qu. Median Mean 3rd Qu. Max.
20 30 40 39 50 55
> summary(systolic)
Min. 1st Qu. Median Mean 3rd Qu. Max.
120 130 140 140 150 160
> plot(systolic,age)
> detach(hypertension)
with()
函数
with ( 数据框名称, {···} )
- 大括号
{}
之间的语句都是针对括号{}
前的数据框名称执行的 - 如果只有一条语句,
{}
可以省略
上面的代码可以重写为:
> with(hypertension,{
+ summary(age)
+ summary(systolic)
+ plot(systolic,age)
+ })
- 局限性:赋值仅在
with()
函数的括号内生效。 - 如果要创建在
with()
结构以外的对象,需使用特殊赋值符号<<-
代替标准赋值符号<-
。<<-
可以将对象保存到with()
之外的全局环境中。
上面的代码可以重写为:
> with(hypertension, {stat <- summary(age)
+ stat})
Min. 1st Qu. Median Mean 3rd Qu. Max.
20 30 40 39 50 55
> with(hypertension, {nonstat <- summary(systolic)
+ stat <<- summary(systolic)})
> nonstat
错误: 找不到对象'nonstat'
> stat
Min. 1st Qu. Median Mean 3rd Qu. Max.
120 130 140 140 150 160
(5)因子(factor)
变量可分为:
- 名义型变量:没有顺序之分的类别变量;
- 有序型变量:表示一种顺序关系,而非数量关系;
- 连续型变量:可以呈现为某个范围内的任意值并同时表示了顺序和数量。
类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。
在R中,因子决定了数据的分析方式以及如何进行结果展示。
因子的设计思想来源于统计学中的名义变量或分类变量,这些变量本质上不是数字,而是对应分类。
在R中,因子可以简单看做一个附加更多信息的向量(尽管他们内部机理是不同的)。这些额外的信息包括向量中不同值的记录,称为“水平”(level)。
- 函数
factor()
以一个整数向量的形式存储类别值,将一个由字符串(原始值)组成的内部向量映射到这些整数上。 - 将数值型的因子转换成数值型向量,需要使用
as.numeric(as.character())
组合函数。其中as.character()
将向量转换成字符型,as.numeric()
函数将向量转换成数值型。
> hypertention <- c("yes", "no", "no", "yes")
> hypertention <- factor(hypertention)
> hypertention
[1] yes no no yes
Levels: no yes
> str(hypertention)
Factor w/ 2 levels "no","yes": 2 1 1 2
因子的长度定义为数据的长度,而不是水平的个数。
> x <- c(5, 12, 13,12)
> x <- factor(x)
> x
[1] 5 12 13 12
Levels: 5 12 13
# x中的不同数值(5,12,13)就是水平
# x的核心是(1,2,3,2),意味着数据是由水平1、水平2和水平3的值构成的,原始数据已经重新编码为水平
> str(x)
Factor w/ 3 levels "5","12","13": 1 2 3 2
> length(x)
[1] 4
> class(x)
[1] "factor"
> x <- as.numeric(x) # 实际效果是将因子水平转换成了数值向量
> x
[1] 1 2 3 2
> x <- as.numeric(as.character(x)) # 将数值型的因子转换成数值型向量
> x
[1] 5 12 13 12
> class(x)
[1] "numeric"
要表示有序变量,需要为函数factor()
指定参数ordered = TRUE
。
> severity <- c("high", "middle", "low", "middle")
> severity <- factor(severity, ordered = TRUE)
# 以上语句将向量编码为(1,3,2,3)
# 并在内部将这些值关联为1=high,2=low以及3=middle
> severity
[1] high middle low middle
Levels: high < low < middle
> str(severity)
Ord.factor w/ 3 levels "high"<"low"<"middle": 1 3 2 3
对于字符型向量,因子的水平默认依字母顺序创建。可以通过指定levels
选项来覆盖默认排序。
需要确保指定的水平与数据中的真实值相匹配,否则,任何在数据中出现而未在参数中列举的数据都将被设为缺失值。
> severity <- factor(severity, ordered = TRUE, levels = c("low", "middle", "high"))
> severity
[1] high middle low middle
Levels: low < middle < high
> str(severity)
Ord.factor w/ 3 levels "low"<"middle"<..: 3 2 1 2
数值型变量可以用levels
和labels
参数编码成因子。
注意标签的顺序必须和水平的顺讯向一致。
sex <- factor(sex, levels = c(1, 2), labels = c("Male", "Female"))
此例中,性别变量被转换成一个无需因子,男性被编码成1,女性被编码成2,标签“Male”和“Famle”将替代1和2在结果中输出。
示例:
> IDnumber <- c(101, 102, 103, 104)
> age <- c(24, 78, 56, 45)
> hypertention <- c("yes", "no", "no", "yes")
> severity <- c("high", "middle", "low", "middle")
> hypertention <- factor(hypertention)
> severity <- factor(severity, ordered = TRUE)
> patientdata <- data.frame(IDnumber, age, hypertention, severity)
> str(patientdata)
'data.frame': 4 obs. of 4 variables:
$ IDnumber : num 101 102 103 104
$ age : num 24 78 56 45
$ hypertention: Factor w/ 2 levels "no","yes": 2 1 1 2
$ severity : Ord.factor w/ 3 levels "high"<"low"<"middle": 1 3 2 3
> summary(patientdata)
IDnumber age hypertention severity
Min. :101.0 Min. :24.00 no :2 high :1
1st Qu.:101.8 1st Qu.:39.75 yes:2 low :1
Median :102.5 Median :50.50 middle:2
Mean :102.5 Mean :50.75
3rd Qu.:103.2 3rd Qu.:61.50
Max. :104.0 Max. :78.00
(6)列表
- 列表就是一些对象(或成分)的有序集合,是R数据类型中最为复杂的一种。
- 列表允许整合若干(可能无关的)对象到单个对象名下。
- 可以使用函数
list()
创建列表。
Mylist <- list ( obj1, obj2, ··· )
也可以为列表中的对象命名:
Mylist <- list ( name1=obj1, name2=obj2, ··· )
- 可以通过在双重方括号中指明代表某个成分的数字或名称来访问列表中的元素。
- 许多
R
函数的运行结果都以列表
的形式返回
> a <- "list example"
> x <- c(1, 2, 3, 4,5)
> matrix <- matrix(1:20, nrow=5, byrow=FALSE)
> k <- c("one", "two", "four")
> mylist <- list(a,x,matrix, k)
> mylist
[[1]]
[1] "list example"
[[2]]
[1] 1 2 3 4 5
[[3]]
[,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
[[4]]
[1] "one" "two" "four"
> mylist[[3]]
[,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
注意事项
对象名称中的句点(
.
)没有特殊意义。但是美元符号(
$
)有着和其它语言中的句点类似的功能,即指定一个数据框或者列表中的某些数据。
R
不提供多行注释或块注释,必须以#
作为多行注释中每一行的开始。调试时,可以把想忽略的代码放到语句
if (FALSE) { ··· }
中,将FALSE
改为TRUE
即允许这块代码执行。将一个值赋值给某个向量、矩阵、数组或列表中一个不存在的元素时,
R
将自动扩展这个数据结构以容纳新值。c <- c(1, 15, 10, 8, 20)
c <- c(1,15,10)
c
[1] 1 15 10
c[5] <- 21
c
[1] 1 15 10 NA 21
c[8] <- 31
c
[1] 1 15 10 NA 21 NA NA 31
c <- c[1:3]
c
[1] 1 15 10
R
中标量以单元素向量的形式出现。R
中的下标索引从1开始,而不是从0开始。R
中变量无法被声明,变量在首次赋值时生效。