R_learning

介于r语言在统计绘图上的强大功能,决定以实用为目的进行粗浅的学习,所使用的教材选择《R语言实战》。代码见RScripts(不要轻易运行以免出现一些奇怪的东西)。

1 Introduce

1.1 帮助功能

函数help.start()会打开浏览器窗口,在其中可以查看帮助手册,问题集以及参考材料,其余的参考表格。尝试后发现,若在VScode中使用该命令,会直接在VScode的窗口中打开该html文件。

1.2 工作空间

即当前R的工作环境,其储存着所有定义的对象,但会话结束时,可将当前工作空间保存到一个镜像中并在下次载入。管理工作空间的函数如下。

注意到,路径应该使用正斜杠/,反斜杠\会被作为转义符,此外setwd()函数只能切换目录而不能常见新的目录。

1.3 包

第一次安装某一个包:install.packages("*")

更新某一个包:update.packages("*")

查看已安装包的描述:installed.packages("*")

包的载入:library(*)


tips:处理大型数据集时需要专门的手段

2 Creat Dataset

R可以处理的数据类型包括数值,字符,逻辑型,复数,字节。

以下图的数据集为例

PatientID是行/实例型变量,AdmDate为日期型变量,Age是连续型(定量型)变量,Daibetes是名义变量,Status是顺序变量。名义变量和顺序变量都是分类变量,但顺序变量具有自然的顺序性。

R会将实例标识符称为rowname,分类变量称为因子。

2.1 数据结构

2.1.1向量

c()创建向量,如:

1
2
3
a <- c(1, 2, 5, 3, 6, -2, 4) # 数值型
b <- c("one", "two", "three") # 字符型
c <- c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE) # 逻辑型

注意,单个向量中的数据类型必须相同。

此外,只含一个元素的向量称为标量,如f <- 3,常用于保存常量。

通过方括号访问向量中的元素,==R中的位置索引从1开始而非从零开始==,可以同时访问多个元素。

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

tips:x:y可以看作是c(x, x+1, x+2,..., y),即一个从x到y的数值型向量,当然,x可以大于y,此时即为c(x, x-1, x-2,..., y)。

2.1.2 矩阵

矩阵为一个二维数组,同样的,其中的每一个元素必须是相同的类型。通过matrix()创建矩阵,通常所用的格式为:

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

其中vector包含矩阵的元素,其后两个参数分别代表了矩阵的的形状,参数byrow表明矩阵的填充方式(默认按列),为一个布尔值。dimnames为可选参数,其中的char_vector_rownameschar_vector_colnames为字符型向量,表明行名和列名。以下为两个示例:

1
2
3
4
5
6
7
y <- matrix(1:20, nrow=5, ncol=4)
# [,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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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))
# C1 C2
#R1 1 26
#R2 24 68

mymatrix <- matrix(cells,
nrow = 2, ncol = 2, byrow = FALSE,
dimnames = list(rnames, cnames))
# C1 C2
#R1 1 24
#R2 26 68

tips:也可以只填写nrowncol中的一个,但参数的位置不能交换。


通过下标和方括号选择矩阵中的行X[i,],列X[,j]或元素X[i,j],通过将i或j定义为数值型向量可以选择多行或者多列。若i和j均为向量,那么所选择的是一个对应的行和列交叉点处的元素组成的新矩阵。

当使用x[i]访问矩阵中的元素时,将访问vector[i],或是说,在选择时不给出坐标形式,那么所访问的结果即是访问vector的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x <- matrix(1:10, nrow = 2)
print(x)
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 3 5 7 9
#[2,] 2 4 6 8 10
print(x[2, ])
#[1] 2 4 6 8 10
print(x[, 2])
#[1] 3 4
print(x[1, 4])
#[1] 7
print(x[1, c(4, 5)])
#[1] 7 9
print(x[2])
#[1] 2

tips:矩阵中无法通过行名和列名访问元素。

2.1.3 数组

作为矩阵的推广,数组可以是多维的,通过array()创建,如:

1
myarray <- array(vector, dimensions, dimnames)

其中dimensions为数值型向量,给出各维度下标的最大值,dimnames为可选变量,为一个包含各维度名称标签的列表,每个维度的名称标签为一个字符型向量。和矩阵一样,数组内的元素只能是一种类型。以下为一个三维(2×3×4)数值型数组。

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
26
27
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))
#, , 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

可以看到,数组的输出为多个矩阵,对于n维数组,将数组从后n-2个维度展开,每一项为一个矩阵进行输出,在每一个矩阵前, , *, *, ...即为对应的后n-2个维度中每一个维度内的编号。

数组中,填充顺序与参数dimensions中的顺序一致,即[1, 1, 1, ...] -> [2, 1, 1, ...] -> ... -> [dimensions[1], 1, 1, ...] -> [1, 2, 1, ...] -> [2, 2, 1, ...] -> ...。即先外层,再内层

2.1.4 数据框

矩阵另一种方式的推广,其不同的列可以包含不同模式的数据,在表2-1中显示的数据集即一个数据框。数据框可以通过data.frame()创建,如:

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

其中col1col2col3可以为任意类型的向量。

当没有指定列名时,R会自动将变量名作为列名:

1
2
3
4
5
6
7
8
9
10
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)
# patientID age diabetes status
#1 1 25 Type1 Poor
#2 2 34 Type2 Improved
#3 3 28 Type1 Excellent
#4 4 52 Type1 Poor

可以用names函数指定列名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
col1 <- c(1, 2, 3, 4)
col2 <- c(25, 34, 28, 52)
col3 <- c("Type1", "Type2", "Type1", "Type1")
col4 <- c("Poor", "Improved", "Excellent", "Poor")
patientdata <- data.frame(col1, col2, col3, col4)
print(patientdata)
# col1 col2 col3 col4
#1 1 25 Type1 Poor
#2 2 34 Type2 Improved
#3 3 28 Type1 Excellent
#4 4 52 Type1 Poor

names(patientdata) <- c("patientID", "age", "diabetes", "status")
print(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

数据框数据的选中有多种方式,可用类似矩阵的下标记号,也可以指定列名:

1
2
3
4
5
6
7
8
9
10
11
12
print(patientdata[1:2])
# patientID age
#1 1 25
#2 2 34
#3 3 28
#4 4 52
print(patientdata[c("diabetes", "status")])
# diabetes status
#1 Type1 Poor
#2 Type2 Improved
#3 Type1 Excellent
#4 Type1 Poor

当用坐标的形式选中时,其表现形式与矩阵的选中一致。注意patientdata[1]patientdata[,1]不同。

而数据框的选中还有一种特殊的形式,即符号$,用于选取一个给定数据框中的某个特定变量。

例如生成diabetesstatus的列联表:

1
2
3
4
print(table(patientdata$diabetes, patientdata$status)
# Excellent Improved Poor
#Type1 1 0 2
#Type2 0 1 0

2.1.4.1 函数with()

以以下为例

1
2
3
summary(mtcars$mpg)
plot(mtcars$mpg, mtcars$disp)
plot(mtcars$mpg, mtcars$wt)

可以简写如下

1
2
3
4
5
with(mtcars,{
summary(mpg)
plot(mpg,disp)
plot(mpg,wt)
})

值得注意的是,赋值只在此函数的括号内生效,若想要全局赋值,则需要使用<<-代替<-

2.1.5 因子

分类变量(名义变量)和有序的分类变量(顺序变量)称为因子

函数factor()以整数向量储存类别值,eg:

1
diabetes <- c("type1", "type2", "type1", "type1")

语句diabetes <- factor(diabetes)将此向量储存为(1,2,1,1)若需要表示顺序变量,则需要指定参数ordered=TRUE

1
status <- c("poor", "improved", "excellent", "poor")

语句diabetes <- factor(status, ordered=TRUE )将此向量储存为(3,2,1,3)

对于字符型向量,默认以字母顺序创建,通过levels覆盖默认排序,如

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

数值型可以用levelslabels来编码成因子,如:

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

2.1.6 列表

mylist <- list(object1, object2, ...),其中的对象可以是任何结构,可以用mylist <- list(name1=object1, name2=object2, ...)为对象命名

用双重方括号[[]]来访问列表中的元素,对于命名成份也可用$字符

2.2 数据的输入

2.3.1 键盘输入

可用mydata <- edit(mydata)或者fix(mydata)调用文本编辑器

2.3.2 带分隔符的文本文件

mydata <-read.table(file,option)导入带分隔符的文本文件

image-20260722160947966

2.3.3 xlsx文件

用readxl包里的read_xlsx(workbook, 1)导入xlsx文件的第一个工作表,保存为数据框

2.3.4 JSON文件

2.3.5 网页

2.3.6 SPSS

haven包中的read.spss()

2.3.7 SAS

......

2.4 数据集的标注

2.4.1 变量标签

2.4.2 值标签

2.5 处理数据对象的实用函数

image-20260722164843920

3 基本数据管理

3.1 创建新变量

1
2
3
4
5
6
7
8
9
10
11
12
13
leadership <- data.frame(
manager = c(1, 2, 3, 4, 5),
date = c("10/24/08", "10/28/08",
"10/1/08", "10/12/08", "5/1/09"),
country = c("US", "US", "UK", "UK", "UK"),
gender = c("M", "F", "F", "M", "F"),
age = c(32, 45, 25, 39, 99),
q1 = c(5, 3, 3, 3, 2),
q2 = c(4, 5, 5, 3, 2),
q3 = c(5, 2, 5, 4, 1),
q4 = c(5, 5, 5, NA, 2),
q5 = c(5, 5, 2, NA, 1)
)
1
2
leadership$total_score <-leadership$q1+leadership$q2+leadership$q3+leadership$q4+leadership$q5
leadership$mean_score <-(leadership$q1+leadership$q2+leadership$q3+leadership$q4+leadership$q5)/5#可以用leadership$total_score

或者

1
2
3
leadership <- transform(leadership,
total_score = q1+q2+q3+q4+q5,
mean_score = (q1+q2+q3+q4+q5)/5)#不能用total_score

3.2 变量的重编码

语句variable[condition] <- expression仅在condition的值为TRUE时执行赋值

1
2
leadership$agecat[leadership$age >=55&
leadership$age <=75]<-"Middle Aged"

within()函数用法类似于with()但可以用于修改数据框,可简化代码

3.3 变量的重命名

fix()函数或者name()函数

3.4 缺失值

is.na(y)函数

1
2
3
y <- c(1,2,3,NA)
is.na(y)
#c(FALSE,FALSE,FALSE,TRUE)

使用函数处理时,多数情况下可以用参数na.rm=TRUE在计算前移除缺失值

1
2
x <-c(1,2,NA,3)
y<-sum(x,na.rm=TRUE)#6

函数na.omit()可以删除所有含有缺失数据的行

3.5 日期值

as.Date(x,"input_format")将字符串转化为日期变量,默认的input_formatyyyy-mm-dd,日期值可以执行算术运算

image-20260723133302098

Sys.Date()返回当天的日期,date()返回当前的日期和时间

format()可以接受一个参数并按某种格式输出结果

1
format(Sys.Date(),format="%B %d %Y")

由于系统设置为中文,此时会输出“七月”,可通过Sys.setlocale("LC_TIME", "English")更改

difftime()可以用于计算时间间隔

1
difftime(date1,date2,units="weeks")

3.6 类型转换

image-20260723134232942

3.7 数据排序

order()可以对数据框排序,默认为升序,在排序变量前加减号即可为降序

1
newdata <- leadership[order(leadership$gender,-leadership$age),]

order()返回的是一个向量,用于表示按顺序排列时的行索引,因此上述代码需要用,表示行索引。

3.8 数据集的合并

3.8.1 在数据框中添加列

即横向合并,使用merge()函数

1
total <- merge(dataframeA,dataframeB,by="ID")

即通过共有变量"ID"合并

也可通过cbind()直接合并两个对象

3.8.2 在数据框中添加行

rbind()函数

3.9 切分数据集

3.9.1 选取变量

3.9.2 剔除变量

eg

1
2
myvars <- names(leadership) %in% c("q3","q4")
newdata <- leadership[!myvars]

第一行生成了逻辑值向量,q3或q4为TRUE,其余为FALSE

1
newdata <- leadership[c(-8,-9)]

的效果也是一样的

1
leadership$q3 <- leadership$q4 <- NULL

将这两列设定为NULL,也是删除

3.9.3 subset()

1
2
3
4
newdata <- subset(leadership, age>=35 | age<23,
select=c(q1,q2,q3,q4))
newdata <- subset(leadership,gender=="M" & age>25,
select=gender:q4)

3.9.4 随机抽样

sample(1:nrow(leadership),3,replace=FALSE)

4 高级数据管理

4.1 数值处理函数和字符处理函数

4.1.1 数学函数

image-20260724104928488
image-20260724104951157

4.1.2 统计函数

image-20260724105031770

4.1.3 概率函数

概率函数形如[dpqr]<概率分布填写>()

d为密度函数,p为分布函数,q为分位数函数,r为生成随机数

image-20260724105204010
1
2
3
4
5
6
7
8
9
10
11
12
library(ggplot2)
x<-seq(from = -3,to =3,by = 0.1)
y = dnorm(x)
data <-data.frame(fx=x,y=y)
ggplot(data = data,aes(x,y))+
geom_line()+
labs(x = "Normal Deviate",
y="Density")+
scale_x_continuous(breaks = seq(-3,3,1))
pnorm(1.96)
qnorm(.9,mean= 500,sd = 100)
rnorm(50,mean = 50,sd = 10)

生成随机数可以用set.seed()设定随机数种子

4.1.4 字符处理函数

image-20260724110327366

4.1.5 其他实用函数

image-20260724111223621

4.1.6 将函数应用于矩阵和数据框

mean()round()log()等函数可以用于矩阵和数据框,结果为对数据框或矩阵中所有数据一并处理

apply(x,MARGIN,FUN,...)可以将任意一个函数运用到任意一个维度上,MARGIN为维度,1为行,2为列,...为传递给FUN的参数

sapply()可以用于列表

4.1.7 一个例子

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
26
27
28
29
30
31
options(digits = 2)

Student <- c("John Davis", "Angela Williams", "Bullwinkle Moose",
"David Jones", "Janice Markhammer", "Cheryl Cushing",
"Reuven Ytzrhak", "Greg Knox", "Joel England",
"Mary Rayburn")
Math <- c(502, 600, 412, 358, 495, 512, 410, 625, 573, 522)
Science <- c(95, 99, 80, 82, 75, 85, 80, 95, 89, 86)
English <- c(25, 22, 18, 15, 20, 28, 15, 30, 27, 18)
roster <- data.frame(Student, Math, Science, English,
stringsAsFactors = FALSE)
print(roster)
z <- scale(roster[, 2:4])
score <- apply(z, 1, mean)
roster <- cbind(roster, score)
y <- quantile(score, c(.8, .6, .4, .2))

roster$grade <- NA
roster <-within(roster,{
grade[score >=y[1]] <-"A"
grade[score <y[1] & score >=y[2]] <-"B"
grade[score <y[2] & score >=y[3]] <-"C"
grade[score <y[3] & score >=y[4]] <-"D"
grade[score < y[4]] <-"F"
})
name<-strsplit((roster$Student)," ")
Firstname<-sapply(name,"[",1)
Lastname<-sapply(name,"[",2)
roster<-cbind(Firstname,Lastname,roster[-1])
roster <-roster[order(Lastname,Firstname),]
print(roster)

将学生的成绩用ABCD表示,并根据姓名排序

4.2 控制流

4.2.1 重复和循环

4.2.1.1 For结构

for (var in seq) statement

4.2.1.2 While结构

while (cond) statement

1
2
i <- 10
while (i>0) {print("Hello");i<- i+1}

换行可以代替分号

4.2.2 条件执行

4.2.2.1 if-else结构

if (cond) statement1 else statement2

4.2.2.2 ifelse结构

ifelse(cond,statement1,statement2)

4.2.2.3 switch结构

示例:

1
2
3
4
5
6
7
8
9
10
11
feelings <- c("sad", "afraid")
for (i in feelings) {
print(
switch(i,
happy = "I am glad you are happy",
afraid = "There is nothing to fear",
sad = "Cheer up",
angry = "Calm down now"
)
)
}

4.3 自定义函数

1
2
3
4
myfunction <- function(arg1, arg2, ...){
statements
return(object)
}

4.4 数据重塑

4.4.1 转置

t()函数,数据框会先被转化为矩阵

4.5 数据汇总

aggregate(x,by,FUN)by是一个变量名组成列表,这些向量名会被去掉以形成新的观测值

1
2
3
4
5
6
options(digits = 3)
print(mtcars)
aggdata <- aggregate(mtcars,
by = list(Cylinders=mtcars$cyl, Gears=mtcars$gear),
FUN = mean, na.rm = TRUE)
print(aggdata)

对于每一个cylgear的组合计算平均数。