什么是R Markdown?
.Rmd文件:在单个文档中同时阐述你的代码和想法。将代码作为单独的块或整个文档运行。
动态文档:将图、表格和结果与叙述性文本结合在一起。渲染为多种格式,如 HTML、PDF、Word 或 PowerPoint。
可重复的研究:上传、分享你的报告。任何人都可以阅读或运行你的代码来重现你的工作。
整体的Workflow是怎样的?
通过“文件”>“新建文件”>“R Markdown”,在 RStudio 中打开一个新的 .Rmd 文件。
将代码嵌入块中。按行、按块或一次全部运行代码。
编写文本并添加表格、图形、图像等元素。使用 Markdown 语法或 RStudio Visual Markdown 编辑器进行格式化。
在 YAML 元数据中设置输出格式,自定义主题或添加参数。
保存并渲染整个文档。定期编织以在写作时实时预览你的作品。
分享你的作品!
R Markdown备忘录可见网站 rmarkdown :: Cheatsheet,其中全面的介绍了rmarkdown包的具体用法。
R Markdown三元素:元数据、文本和代码。
元数据写在一对三个破折号之间。 元数据的语法是YAML(YAML Ain’t Markup Language),所以有时也称为YAML元数据。
在文档的YAML区域设置输出格式,并使用输出选项对其进行自定义。一个简单的例子:
---
title: "Hello R Markdown"
author: "Me"
date: "2018-02-14"
output: html_document
---
每种输出格式通常都带有格式选项,这些选项都记录在 R 包帮助页面上。
例如,你可以在R中输入 ?html_document 来打开
html_document 格式的帮助页面,从中可以看到
html_document 格式文档可以设置的所有参数。
注意!YAML中的缩进很重要,在设置各种选项时一定要注意控制缩进。
例如,本文档的元数据:
---
title: "R与R Markdown"
date: "最后编译于09/11/2024"
output:
html_document:
toc: TRUE
toc_float:
collapsed: TRUE
smooth_scroll: TRUE
number_sections: TRUE
---
| 选项 | 作用 |
|---|---|
toc: TRUE |
在输出中包含目录 |
toc_float: TRUE |
将目录浮动到主文档的左侧。除了TRUE,你还可以传递控制浮动目录行为的选项列表 |
collapsed: TRUE |
(默认为TRUE)控制目录是否仅显示顶级标题。折叠时,目录会在必要时自动展开 |
smooth_scroll: TRUE |
(默认为TRUE)控制当通过鼠标单击导航到目录项时是否为页面滚动设置动画 |
number_sections: TRUE |
对章节标题进行编号 |
R Markdown 文档中的文本是使用 Markdown 语法编写的。
如果文本被星号包围,例如*text*,则文本将为斜体。
粗体文本是使用一对双星号 (**text**)
生成的。一对波浪号 (~)
将文本转换为下标(例如,H~3~ 呈现 H3)。
一对插入符 (^) 产生一个上标(例如,A^2^ 呈现
A2)。
要将文本高亮标记为文本,请使用一对反引号,例如,`code`。
要包含 \(n\) 个反引号,请在外部至少使用
\(n+1\)
个反引号,例如,你可以使用四个反引号以在内部保留三个反引号:```` ```代码``` ````,呈现为```代码```。
超链接是使用语法<link>或[text](link)创建的。例如,<https://www.rstudio.com>
和 [RStudio](https://www.rstudio.com) 分别呈现 https://www.rstudio.com
和 RStudio。
本文档中的各种元素(章节名、列表等)也都是基于Markdown语法,大家可以对照Cheatsheeet和本文档的源代码学习。
你可以使用 RStudio
工具栏(插入按钮)或键盘快捷键Ctrl + Alt + I(macOS
上的Cmd + Option + I)插入 R 代码块。 当你运行.Rmd
文件时,R Markdown将运行每个代码块并将结果嵌入到代码块下方。
你可以在代码块中做很多事情:生成文本输出、表格或图形。例如:
text <- "hello world!"
text
## [1] "hello world!"
x <- 1
x
## [1] 1
knitr::kable(iris[1:5, ])
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
plot(cars, pch = 19)
可以使用代码块选项自定义输出方式,在块头的 {} 中设置参数。
| 选项 | 默认值 | 作用 |
|---|---|---|
eval |
TRUE | 是否运行代码块 |
echo |
TRUE | 是否在输出文档中显示源代码(有人可能不喜欢阅读你的代码而只想看结果) |
warning |
TRUE | 是否显示警告 |
message |
TRUE | 是否显示信息 |
error |
FALSE | TRUE:在文档中显示错误消息,FALSE:发生错误时停止运行 |
include |
TRUE | 是否在输出文档中包含代码块。如果
include=FALSE,R Markdown
仍然运行块,其结果可以被其他块使用。 |
collapse |
FALSE | 将所有源代码和输出折叠到一个块中 |
要设置适用于文件中每个块的全局选项,在代码块中调用
knitr::opts_chunk$set。R Markdown会将你传递给
knitr::opts_chunk$set 的每个选项视为全局默认值。
通过用 `r ` 将代码括起来,可以将代码结果直接插入到 .Rmd
文件的文本中。R Markdown 总是会显示代码的结果,而不是显示代码本身。
例如,1+1等于2。
通过 RStudio 中的新建文档的方式编译你的第一个 .Rmd 文件,熟悉常用的 R Markdown 技巧和 RStudio 操作。
通过创建一个简短的简历练习你所学。要求:title必须是你的名字;应该包含章节主题(headings),例如教育背景和工作经历,每一部分应该包括工作/学历的项目列表(bulleted list)。
函数的帮助可用help(cor),?cor,??cor.
R程序包是多个函数的集合,具有详细的说明和实例,每个程序包包括R函数,数据,帮助文件,描述文件等。
#install.packages('praise')
library(praise)
praise()
## [1] "You are astonishing!"
要高效地使用 R 语言编程,你需要深入了解基本的数据类型和数据结构,以及如何对它们进行操作。最常用的数据类型包括:
"RStudio", "R is so good!"24, 24.8TRUE, FALSE这些数据类型的元素可以组合形成数据结构,包括:向量vector、矩阵matrix、数据框data frame、列表list。
列出当前所有对象,删除对象
ls() #当前工作空间中所有对象
## [1] "text" "x"
rm(list='x') # 删除名为x的对象
rm(list=ls()) # 删除一切对象
每次与R的会话,都建立了一个工作空间workspace,
可用save.image(),save(object list, file="xxx.Rdata").
向量是 R 中最常见和最基本的数据结构。
最简单的方式,你可以使用logical()、character()
和 numeric() 创建对应数据类型的向量。
logical(5)
## [1] FALSE FALSE FALSE FALSE FALSE
character(5)
## [1] "" "" "" "" ""
numeric(5)
## [1] 0 0 0 0 0
你还可以通过直接指定其内容来创建向量,
R会自动猜测向量的存储格式。该函数是 c()(用于
combine),括号内的任何元素(用逗号隔开)都会拼接成一个向量。
x <- c(1, 2, 3,4,5,6)
x
## [1] 1 2 3 4 5 6
y <- c(TRUE, TRUE, FALSE, FALSE)
y
## [1] TRUE TRUE FALSE FALSE
y <- c(TRUE, TRUE, FALSE, FALSE,3)
y
## [1] 1 1 0 0 3
z <- c("机器学习", "人工智能")
z
## [1] "机器学习" "人工智能"
c()也可以对一个向量继续增加元素。
z <- c(z, "深度学习")
z
## [1] "机器学习" "人工智能" "深度学习"
z <- c("数据科学", z)
z
## [1] "数据科学" "机器学习" "人工智能" "深度学习"
你可以使用seq()和rep()将向量创建为有规律的数字向量。
x <- 1:10
x
## [1] 1 2 3 4 5 6 7 8 9 10
y <- seq(1,10)
y
## [1] 1 2 3 4 5 6 7 8 9 10
z <- seq(from = 1, to = 2, by = 0.1)
z
## [1] 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0
z1 <- rep(0, 10)
z1
## [1] 0 0 0 0 0 0 0 0 0 0
R 支持向量中的缺失数据。 它们表示为 NA(Not
Available),可用于所有向量类型。
函数is.na()指示代表缺失数据的向量元素,如果向量包含任何缺失值,函数anyNA()返回
TRUE。
x <- c("a", NA, "c", "d", NA)
is.na(x)
## [1] FALSE TRUE FALSE FALSE TRUE
anyNA(x)
## [1] TRUE
可以使用数字索引从向量、矩阵或数据框中提取元素。有很多方法可以做到这一点。
x <- c(1,4,4,NA,2,2,3)
x[1]
## [1] 1
x[1:3]
## [1] 1 4 4
x[c(5,7)]
## [1] 2 3
x[-7]
## [1] 1 4 4 NA 2 2
x[!is.na(x)]
## [1] 1 4 4 2 2 3
可以利用cbind()进行列向量合并,利用rbind()合并行向量,同样适用于矩阵。
x <- 1:3
y <- 10:12
cbind(x, y)
## x y
## [1,] 1 10
## [2,] 2 11
## [3,] 3 12
rbind(x, y)
## [,1] [,2] [,3]
## x 1 2 3
## y 10 11 12
一些有用的向量函数:
x1 <- x[!is.na(x)]
x1
## [1] 1 2 3
which(x1==4)
## integer(0)
sort(x1)
## [1] 1 2 3
order(x1)
## [1] 1 2 3
rev(x1)
## [1] 3 2 1
unique(x1)
## [1] 1 2 3
table(x1)
## x1
## 1 2 3
## 1 1 1
因子: 因子用于表示分类数据。因子可以是有序的或无序的。对于统计分析和绘图很重要。
虽然因子经常看起来像字符型向量,但它们实际上是整数,在将它们视为字符时需要非常小心。
创建后,因子只能包含预定义的设定值,称为水平(levels)。 默认情况下,R 始终按首字母顺序对水平进行排序。
factor()函数用于在 R 中创建和修改因子:
sex <- factor(c("male", "female", "female", "male"))
sex
## [1] male female female male
## Levels: female male
有时,因子的顺序并不重要。但有时你希望指定顺序,因为它有意义(例如,“低”、“中”、“高”)。此外,指定水平的顺序可以帮助我们比较水平:
food <- factor(c("low", "high", "medium", "high", "low", "medium", "high"))
levels(food)
## [1] "high" "low" "medium"
food <- factor(food, levels = c("low", "medium", "high"))
levels(food)
## [1] "low" "medium" "high"
min(food)
## Error in Summary.factor(structure(c(1L, 3L, 2L, 3L, 1L, 2L, 3L), .Label = c("low", : 'min' not meaningful for factors
food <- factor(food, levels = c("low", "medium", "high"), ordered = TRUE)
min(food)
## [1] low
## Levels: low < medium < high
随机数生成: 可以利用rnorm()
函数生成一个服从正态分布的随机向量,第一个参数 n
即为样本大小。
x <- rnorm(5)
x
## [1] -0.40960694 -1.12764458 0.12067781 -0.08370293 0.11162651
每次我们调用这个函数,都会得到不同的随机数。
有时我们希望我们的代码重现完全相同的结果。 我们可以使用
set.seed() 函数来做到这一点。
set.seed(2024)
x <- rnorm(5)
set.seed(NULL)
x
## [1] 0.9819694 0.4687150 -0.1079713 -0.2128782 1.1580985
默认情况下,rnorm() 创建标准正态随机变量,均值为
0,标准差为 1。可以使用 mean 和 sd
参数更改均值和标准差。
x <- rnorm(5, mean = 10, sd=2)
x
## [1] 7.472027 10.784922 12.011800 11.085119 11.641709
x <- rnorm(10, -10, 5)
x
## [1] -8.1439462 -4.5078629 -6.7802389 -17.4799380 -13.7136552 -4.7502033
## [7] -8.7626431 -17.0858539 -0.4567072 -4.3239468
mean() 和 var()
函数可用于计算数字向量的均值和方差。 sd()
函数可以计算标准差。
y <- rnorm(100)
mean(y)
## [1] 0.1045968
var(y)
## [1] 0.9228385
sd(y)
## [1] 0.9606448
同样,你可以使用 rt()、runif()
从t分布、均匀分布等其他分布生成随机数。
随机抽样函数sample(x, size, replace=FALSE, prob=NULL):
从x中随机取样,取样size个,默认无放回,等概率。
sample(1:10, 4) #从1到10中取样,并从中不放回地抽取4个数字
## [1] 8 6 5 7
sample(1:10) #从1到10中进行无放回地取10个数字
## [1] 1 3 2 8 5 7 4 10 9 6
sample(1:10, replace=T) #从1到10中进行有放回地取10个数字
## [1] 5 1 1 10 5 10 1 5 5 9
sample(1:10,10,replace=TRUE)
## [1] 9 8 9 6 5 10 7 2 1 8
sample(letters, 5)
## [1] "u" "g" "e" "a" "x"
sample(c("H","T"),10,prob=c(0.5,0.5),replace=TRUE)
## [1] "H" "H" "H" "T" "H" "H" "H" "T" "T" "T"
sample(c("H","T"),10,prob=c(0.8,0.2),replace=TRUE)
## [1] "H" "H" "H" "H" "H" "H" "T" "H" "H" "H"
在电脑上生成随机数字时,生成的数字并不是真正的随机数,设置随机数字生成器种子(seed)是非常重要的
课重复结果,set.seed(一个整数)。
rnorm(10)
## [1] -0.1227425 0.1571038 -1.2431847 1.0254386 0.6832730 -0.7305534
## [7] 1.2609388 1.0576906 0.6672359 0.9098757
rnorm(10)
## [1] -0.35195837 -0.47336419 0.08025396 -0.18289575 -1.46264301 0.59397928
## [7] -1.39544955 0.81349122 -1.32241957 -0.83179092
set.seed(1)
rnorm(10)
## [1] -0.6264538 0.1836433 -0.8356286 1.5952808 0.3295078 -0.8204684
## [7] 0.4874291 0.7383247 0.5757814 -0.3053884
rnorm(10)
## [1] 1.51178117 0.38984324 -0.62124058 -2.21469989 1.12493092 -0.04493361
## [7] -0.01619026 0.94383621 0.82122120 0.59390132
set.seed(1)
rnorm(10)
## [1] -0.6264538 0.1836433 -0.8356286 1.5952808 0.3295078 -0.8204684
## [7] 0.4874291 0.7383247 0.5757814 -0.3053884
rnorm(10)
## [1] 1.51178117 0.38984324 -0.62124058 -2.21469989 1.12493092 -0.04493361
## [7] -0.01619026 0.94383621 0.82122120 0.59390132
matrix() 函数可用于创建数字矩阵。 在使用
matrix() 函数之前,我们可以通过 ?matrix
了解更多信息。 首先,我们创建一个简单的矩阵。
A <- matrix(data = 1:16, nrow = 4, ncol = 4)
A
## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 13
## [2,] 2 6 10 14
## [3,] 3 7 11 15
## [4,] 4 8 12 16
如前所述,我们可以省略键入 data=、nrow= 和
ncol= 并键入
matrix(1:16, 4, 4),这会产生相同的效果。
如本例所示,默认情况下 R 通过填充列来创建矩阵。可以使用
byrow = TRUE 按行的顺序填充矩阵。
mdat <- matrix(c(1,2,3, 11,12,13), nrow = 2, ncol = 3, byrow = TRUE)
mdat
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 11 12 13
dim() 函数输出给定矩阵的行数和列数。
dim(mdat)
## [1] 2 3
nrow(mdat)
## [1] 2
ncol(mdat)
## [1] 3
要索引 A 中的元素,键入 A[2,3]
将选择对应于第二行和第三列的元素。
A <- matrix(1:16, 4, 4)
A
## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 13
## [2,] 2 6 10 14
## [3,] 3 7 11 15
## [4,] 4 8 12 16
A[2,3]
## [1] 10
A[1,]
## [1] 1 5 9 13
A[,1]
## [1] 1 2 3 4
我们还可以一次选择多行和多列,方法是提供向量作为索引。
A[c(1, 3), c(2, 4)]
## [,1] [,2]
## [1,] 5 13
## [2,] 7 15
A[1:3, 2:4]
## [,1] [,2] [,3]
## [1,] 5 9 13
## [2,] 6 10 14
## [3,] 7 11 15
A[1:2, ]
## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 13
## [2,] 2 6 10 14
A[, 1:2]
## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
A[-c(1, 3), ]
## [,1] [,2] [,3] [,4]
## [1,] 2 6 10 14
## [2,] 4 8 12 16
可以应用于标量的函数通常也可以应用于向量和矩阵。例如,sqrt()
函数返回向量或矩阵的每个元素的平方根。 命令 x^2 将 x
的每个元素求平方。
x <- matrix(c(1, 2, 3, 4), 2, 2, byrow = TRUE)
sqrt(x)
## [,1] [,2]
## [1,] 1.000000 1.414214
## [2,] 1.732051 2.000000
x^2
## [,1] [,2]
## [1,] 1 4
## [2,] 9 16
x+2
## [,1] [,2]
## [1,] 3 4
## [2,] 5 6
t(x) #转置
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
x*x #对应元素相乘
## [,1] [,2]
## [1,] 1 4
## [2,] 9 16
x%*%x #矩阵运算
## [,1] [,2]
## [1,] 7 10
## [2,] 15 22
rowSums(x) # 按行加和
## [1] 3 7
colSums(x)# 按列加和
## [1] 4 6
rowMeans(x) #按行平均
## [1] 1.5 3.5
colMeans(x) #按列平均
## [1] 2 3
apply(X, margin, Fun),
margin为1时对行,2对列
apply ( x,1,sum ) #按行求和
## [1] 3 7
apply ( x,2,sum ) #按列求和
## [1] 4 6
score1 <- c(100,90,80,100,80)
score2 <- c(98,85,70,80,90)
z<-cbind(score1,score2)
### 练习:给出两次考试的均值 apply(z,?,?)
### 练习:给出每个人的平均成绩 apply(z,?,?)
在 R 中,列表充当容器。列表的功能十分强大,内容可以包含任何数据类型的混合。
使用 list() 创建列表:
x <- list(1, "a", TRUE)
x
## [[1]]
## [1] 1
##
## [[2]]
## [1] "a"
##
## [[3]]
## [1] TRUE
也可以使用as.list()将向量转换为列表:
x <- 1:3
x <- as.list(x)
x
## [[1]]
## [1] 1
##
## [[2]]
## [1] 2
##
## [[3]]
## [1] 3
列表的元素可以命名
x <- list(name = "小明", data=c(177,67))
x
## $name
## [1] "小明"
##
## $data
## [1] 177 67
笔记: 列表在函数内部非常有用。 因为 R中的函数只能返回一个对象,所以你可以将许多不同类型的结果拼接,并通过函数可以返回的单个对象输出。
元素由双括号索引。如果列表的元素已命名,则可以通过$符号(即x$data)引用它们。
x[[1]]
## [1] "小明"
x$data
## [1] 177 67
x$data[1]
## [1] 177
数据框是 R 中非常重要的数据类型。它几乎是大多数表格数据的数据结构,也是我们用于统计的数据结构。
数据框是一种特殊类型的列表,其中列表的每个元素都具有相同的长度(即数据框是一个”矩形”列表)。
有关数据框的一些附加信息:
read.csv()和read.table()创建,即将数据导入
R 时。后续讨论as.matrix()将数据框转换为矩阵。data.frame() 函数创建一个新的数据框。1, 2,..., n。dat <- data.frame(id = letters[1:10], x = 1:10, y = 11:20)
dat
## id x y
## 1 a 1 11
## 2 b 2 12
## 3 c 3 13
## 4 d 4 14
## 5 e 5 15
## 6 f 6 16
## 7 g 7 17
## 8 h 8 18
## 9 i 9 19
## 10 j 10 20
一些有用的数据框函数:
head() - 显示前六行tail() - 显示后六行dim() - 返回数据框的维度(即行数和列数)nrow() - 行数ncol() - 列数head(dat)
## id x y
## 1 a 1 11
## 2 b 2 12
## 3 c 3 13
## 4 d 4 14
## 5 e 5 15
## 6 f 6 16
dim(dat)
## [1] 10 3
nrow(dat)
## [1] 10
ncol(dat)
## [1] 3
由于数据框也是列表,因此可以使用列表符号来引用列(此类列表的元素),即[[ ]]或$。
dat[[1]]
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
dat$id
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
dat[,1]
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
dat[1,]
## id x y
## 1 a 1 11
每个元素都有自己的属性,查看属性
x <- c(0.5, 0.6) ## numeric
mode(x)
## [1] "numeric"
x <- c(TRUE, FALSE) ## logical
mode(x)
## [1] "logical"
x <- c(T, F) ## logical
mode(x)
## [1] "logical"
x <- c("M", "F") ## character
mode(x)
## [1] "character"
属性的判断与转化
x = 0:6
is.numeric(x)
## [1] TRUE
is.character(x)
## [1] FALSE
as.logical(x)
## [1] FALSE TRUE TRUE TRUE TRUE TRUE TRUE
as.character(x)
## [1] "0" "1" "2" "3" "4" "5" "6"
is.character(x)
## [1] FALSE
x = c("a","b","c")
as.numeric(x)
## Warning: 强制改变过程中产生了NA
## [1] NA NA NA
as.logical(x)
## [1] NA NA NA
使用rep()函数创造向量
1,1,1,1,1,2,2,2,2,2 并将其命名为 x1。
使用rep()函数创造向量
1,2,1,2,1,2,1,2,1,2 并将其命名为 x2。
将 x1 和 x2 按列组合成矩阵
x.col,即 x1 和 x2 是
x 的两列。
将 x1 和 x2 按行组合成矩阵
x.row,即 x1 和 x2 是
x 的两行。
找到两种方法来计算 x.row 的每一列的总和。
将1,2,..., 20
构成两个4*5的矩阵,其中矩阵A是按列输入,矩阵B是按行输入,并基于A和B生成如下矩阵C-H并输出:
工作目录:读取外部文件和保存结果到外部文件夹的默认路径
getwd()
## [1] "/Users/liting/Documents/SUFE/课程/机器学习/2024/课件/Ch_R语言介绍"
#setwd()
mydata <- read.table("Rreaddata.txt")
mydata
## V1 V2 V3
## 1 M 65 168
## 2 M 70 172
## 3 F 54 156
## 4 F 58 163
mydata <- read.csv("Rreaddata.txt",header=FALSE, sep=" ")
mydata
## V1 V2 V3
## 1 M 65 168
## 2 M 70 172
## 3 F 54 156
## 4 F 58 163
mydata <- read.csv("Rreaddata.csv",header=T, sep=",")
mydata
## Gender Weight Height
## 1 M 65 168
## 2 M 70 172
## 3 F 54 156
## 4 F 58 163
mydata <- read.csv("Rreaddata.csv")
mydata
## Gender Weight Height
## 1 M 65 168
## 2 M 70 172
## 3 F 54 156
## 4 F 58 163
数据输出
d <- data.frame(obs = c(1, 2, 3), treat = c("A", "B", "A"),weight = c(2.3, NA, 9))
write.table(d, file = "foo.txt",row.names = F)
write.csv(d, file = "foo.csv",row.names = F)
save(d, file = "foo.Rdata")
当我们使用 R 进行编程时,我们通常希望控制代码的特定部分何时以及如何执行。可以使用 if-else 语句、for 循环和 while 循环等控制结构来做到这一点。
控制结构是代码块,它们根据指定的参数确定其他代码段的执行方式。 你可以把这些想成有点像父母在离开家之前给孩子的指示:
“如果我晚上 8 点之前没回家,你自己做晚饭吧。”
为了使用控制结构,我们需要创建结果为 TRUE 或 FALSE 的语句。 在上面的孩子示例中,声明”现在是晚上 8 点。 我爸妈在家吗?” 产生 TRUE(“是”)或 FALSE(“否”)。在 R 中,评估某事物为 TRUE 或 FALSE 的最基本方法是通过比较运算符。
以下是在 R 中使用控制结构的六个基本比较运算符:
== 表示相等。x == a
表示:x的值等于a吗?
!= 表示”不等于”。x != b 表示:x
的值不等于 b 吗?
< 表示”小于”。x < c 表示:x
的值是否小于 c?
<= 表示”小于等于”。x <= d 表示:x
的值是否小于或等于 d?
> 表示”大于”。x > e 表示:x
的值是否大于 e?
>= 表示”大于等于”。x >= f 表示:x
的值是否大于或等于 f ?
team_A <- 3 # A队进球数
team_B <- 1 # B队进球数
if (team_A > team_B){
print ("A队获胜")
}
## [1] "A队获胜"
因为 A 队的进球比 B 队多,条件语句 (team_A > team_B)
的计算结果为 TRUE,所以它下面的代码块运行,输出”A
队赢得比赛”的消息。
如果B队进球数更多呢?
team_A <- 1
team_B <- 3
if (team_A > team_B){
print ("A队获胜")
} else {
print ("B队获胜")
}
## [1] "B队获胜"
回顾一下:
如果有多于两条路径呢?
team_A <- 2
team_B <- 2
if (team_A > team_B){
print ("A队获胜")
} else if (team_A < team_B){
print ("B队获胜")
} else {
print("两队打成平手")
}
## [1] "两队打成平手"
现在我们已经在 R 中使用if-else来显示一场比赛的结果,如果我们想查找多场比赛的结果怎么办?假设我们有一个包含多场比赛结果的向量列表:
matches <- list(c(2,1),c(1,2),c(6,3))
假设 A 队的进球数列在第一位(向量的第一个索引),B 队的进球数列在第二位,我们可以在 R 中使用 if-else 找到结果:
if (matches[[1]][1] > matches[[1]][2]){
print ("A队获胜")
} else {
print ("A队战败")
}
## [1] "A队获胜"
if (matches[[2]][1] > matches[[2]][2]){
print ("A队获胜")
} else {
print ("A队战败")
}
## [1] "A队战败"
if (matches[[3]][1] > matches[[3]][2]){
print ("A队获胜")
} else {
print ("A队战败")
}
## [1] "A队获胜"
此代码有效,但我们很容易发现问题。三场比赛已经很麻烦了,如果我们有1000场比赛怎么办?
我们可以通过使用 R 中的 for
循环执行相同的操作来改进我们的代码。for
循环为对象中的每个元素重复一段代码多次。这使我们可以编写更少的代码(这意味着出错的可能性更小)并且可以更好地表达我们的意图:
for (value in sequence){
code block
}
让我们看一个具体的例子。我们将编写一个快速循环来打印列表中项目的值:
teams <- c("A队","B队")
for (value in teams){
print(value)
}
## [1] "A队"
## [1] "B队"
下面我们结合if-else语句和for循环来实现多场比赛的高效评估:
matches <- list(c(2,1),c(1,2),c(6,3))
for (match in matches){
if (match[1] > match[2]){
print("A队获胜")
} else {
print ("A队战败")
}
}
## [1] "A队获胜"
## [1] "A队战败"
## [1] "A队获胜"
R 使用函数来执行操作。 有了函数,你几乎可以做任何事。
要运行名为 func 的函数,我们键入
func(input1, input2, ...),其中参数 input1 和
input2 告诉 R 如何运行该函数。
部分函数在预装包当中,可直接使用。 有些函数只有在使用
install.packages() 和 library()
安装并加载相应的包后才能使用。
你也可以编写自己的函数以进行重复操作。 例如:
add1 <- function(a=1,b=2){
c <- a+b
return(c)
}
add1()
## [1] 3
add1(a=5,b=8)
## [1] 13
如果参数有默认值,不传入参数值就会按照默认值自动计算。
我们可以在上面的 add1() 命令中省略键入 a=
和 b=:也就是说,我们可以只键入
add1(5,8),这会产生相同的效果。
但是,有时指定传入参数的名称可能很有用,因为否则R将假定函数参数以函数帮助文件中给出的相同顺序传递到函数中。此时,如果参数很多,不进行名称指定将很容易报错。
add1(5,8)
## [1] 13
add1(b=8,a=12)
## [1] 20
add1(a=1,b=2,g=3)
## Error in add1(a = 1, b = 2, g = 3): 参数没有用(g = 3)
add1(8,"a")
## Error in a + b: 二进列运算符中有非数值参数
创建一个名为 func() 的函数,该函数有一个名为
lst 的参数。
lst
中具有奇数索引的每个元素。然后该函数应该返回这个新向量。func(c(4, 3, 7, 10, 11, -2)) 应返回向量
c(4, 7, 11)。回顾概率论与数理统计中正态样本的均值参数的区间估计, 设\(x_1, \dots, x_n\)是来自正态均值为\(\mu\),标准差为\(\sigma\)的正态分布的一个样本,则μ的置信度为\(1-\alpha\)的95%置信区间为\([\bar x-1.96 s/\sqrt{n}, \bar x+1.96 s/\sqrt{n}]\).
(1). 按下列要求生成R函数: 函数名:takeCI; 输入: (1)数值型向量x,表示某正态样本的取值. 输出: 基于该样本得到的均值参数的置信度为95%的置信区间,以一个长度为2的向量输出。(提示:可用mean(),sd()函数)
(2). 从均值为10,标准差为1的正态分布中随机生成样本量n=20的一个样本\(x\)。基于此样本,用(1)中函数计算均值参数的95%置信区间并输出
plot() 函数是在 R
中绘制数据的主要方法。例如,plot(x, y) 生成 x 中的数字与 y
中的数字的散点图。 还有许多其他选项,例如,传入参数 xlab
将在 x 轴上产生一个标签。 要了解更多信息,请输入?plot。
x <- rnorm(100)
y <- rnorm(100)
plot(x, y, xlab = "this is the x-axis", ylab = "this is the y-axis", main = "Plot of X vs Y")
plot(x,type='o',pch=2,lty=1,col='blue')
一个创建优雅图形的强大包是ggplot2。它通过将图形分解为多个层次来理解和构建图形。
例如:
library(ggplot2)
ggplot(mpg, aes(displ, hwy, colour = class)) + geom_point()
我们不会详细介绍 ggplot2。如果你对ggplot2感兴趣,建议你访问https://ggplot2.tidyverse.org/。
对于大多数数据分析来说,第一步是将数据集导入 R
中。read.table()
函数是执行此操作的主要方法之一。我们可以使用函数
write.table() 来从 R 中导出数据。
为了说明read.table() 函数,我们现在利用其加载文本文件
Auto.data。以下命令会将文件加载到 R 中并将其存储为名为
Auto 的数据框。 head()
函数也可用于查看数据的前几行。
Auto <- read.table("Auto.data")
Auto[c(1:5,34),]
## V1 V2 V3 V4 V5 V6 V7 V8
## 1 mpg cylinders displacement horsepower weight acceleration year origin
## 2 18.0 8 307.0 130.0 3504. 12.0 70 1
## 3 15.0 8 350.0 165.0 3693. 11.5 70 1
## 4 18.0 8 318.0 150.0 3436. 11.0 70 1
## 5 16.0 8 304.0 150.0 3433. 12.0 70 1
## 34 25.0 4 98.00 ? 2046. 19.0 71 1
## V9
## 1 name
## 2 chevrolet chevelle malibu
## 3 buick skylark 320
## 4 plymouth satellite
## 5 amc rebel sst
## 34 ford pinto
Auto 数据框有些不对劲。你注意到了吗?
R 假定变量名称是数据的一部分,因此将它们包含在第一行中。 在
read.table() 函数中使用选项 header = TRUE 告诉
R:文件的第一行是变量名。
该数据集还包括一些缺失值,用?表示。
缺失值在真实数据集中很常见。使用选项 na.strings告诉
R,任何时候它看到一个特定字符,都应将其视为数据矩阵的缺失元素。
Auto <- read.table("Auto.data", header = TRUE, na.strings = "?", stringsAsFactors = TRUE)
Auto[c(1:4,33),]
## mpg cylinders displacement horsepower weight acceleration year origin
## 1 18 8 307 130 3504 12.0 70 1
## 2 15 8 350 165 3693 11.5 70 1
## 3 18 8 318 150 3436 11.0 70 1
## 4 16 8 304 150 3433 12.0 70 1
## 33 25 4 98 NA 2046 19.0 71 1
## name
## 1 chevrolet chevelle malibu
## 2 buick skylark 320
## 3 plymouth satellite
## 4 amc rebel sst
## 33 ford pinto
stringsAsFactors = TRUE告诉R,任何包含字符串的变量都应被解释为分类变量,并且每个不同的字符串代表该分类变量的不同水平。
将数据从 Excel 加载到 R 中的一种简单方法是将其保存为
csv(逗号分隔值)文件,然后使用 read.csv() 函数。
Auto <- read.csv("Auto.csv", header=TRUE, na.strings = "?", stringsAsFactors = TRUE)
head(Auto)
## mpg cylinders displacement horsepower weight acceleration year origin
## 1 18 8 307 130 3504 12.0 70 1
## 2 15 8 350 165 3693 11.5 70 1
## 3 18 8 318 150 3436 11.0 70 1
## 4 16 8 304 150 3433 12.0 70 1
## 5 17 8 302 140 3449 10.5 70 1
## 6 15 8 429 198 4341 10.0 70 1
## name
## 1 chevrolet chevelle malibu
## 2 buick skylark 320
## 3 plymouth satellite
## 4 amc rebel sst
## 5 ford torino
## 6 ford galaxie 500
dim(Auto)
## [1] 397 9
dim() 函数告诉我们:数据有 397
个观测或行,每个观测有九个变量。
有多种方法可以处理缺失值。在这个数据中,只有五行包含缺失的观察值,因此我们选择使用
na.omit() 函数来简单地删除这些行:
Auto <- na.omit(Auto)
dim(Auto)
## [1] 392 9
正确加载数据后,我们可以使用names() 来检查变量名称:
names(Auto)
## [1] "mpg" "cylinders" "displacement" "horsepower" "weight"
## [6] "acceleration" "year" "origin" "name"
我们可以使用 plot() 函数来生成定量变量的散点图。
然而,简单地键入变量名称会产生错误消息,因为 R 不知道要在 Auto
数据集中查找这些变量。
plot(cylinders, mpg)
## Error in plot(cylinders, mpg): 找不到对象'cylinders'
要引用一个变量,我们必须键入数据集和用 $ 符号连接的变量名。
plot(Auto$cylinders, Auto$mpg)
cylinders 变量存储为数字向量,因此 R 已将其视为定量变量。
但是,由于圆柱体的可能值很少,因此可能更愿意将其视为定性变量。
as.factor() 函数将定量变量转换为定性变量。
attach(Auto)
cylinders <- as.factor(cylinders)
plot(cylinders, mpg, col = "red", varwidth = TRUE, xlab = "cylinders", ylab = "MPG")
hist(mpg, col = "blue")
pairs(~mpg + displacement + horsepower + weight + acceleration, data = Auto
)
summary(Auto)
## mpg cylinders displacement horsepower weight
## Min. : 9.00 Min. :3.000 Min. : 68.0 Min. : 46.0 Min. :1613
## 1st Qu.:17.00 1st Qu.:4.000 1st Qu.:105.0 1st Qu.: 75.0 1st Qu.:2225
## Median :22.75 Median :4.000 Median :151.0 Median : 93.5 Median :2804
## Mean :23.45 Mean :5.472 Mean :194.4 Mean :104.5 Mean :2978
## 3rd Qu.:29.00 3rd Qu.:8.000 3rd Qu.:275.8 3rd Qu.:126.0 3rd Qu.:3615
## Max. :46.60 Max. :8.000 Max. :455.0 Max. :230.0 Max. :5140
##
## acceleration year origin name
## Min. : 8.00 Min. :70.00 Min. :1.000 amc matador : 5
## 1st Qu.:13.78 1st Qu.:73.00 1st Qu.:1.000 ford pinto : 5
## Median :15.50 Median :76.00 Median :1.000 toyota corolla : 5
## Mean :15.54 Mean :75.98 Mean :1.577 amc gremlin : 4
## 3rd Qu.:17.02 3rd Qu.:79.00 3rd Qu.:2.000 amc hornet : 4
## Max. :24.80 Max. :82.00 Max. :3.000 chevrolet chevette: 4
## (Other) :365
本练习涉及波士顿住房数据集。 首先,加载波士顿数据集。
波士顿数据集是ISLR2库的一部分。 当然,您应该在使用前安装
ISLR2 包。 在 library(ISLR2)
之后,数据集包含在对象 Boston 中。
使用?Boston阅读有关数据集的信息。
range()函数来回答这个问题。第一次作业即为本Rmd文档中所有的练习,请大家汇总到一个新的Rmd文档中,于下周日9.22晚24点前提交以HW2+学号+姓名.html/pdf文件至Canvas。