0%

R 入门手册

1. 认识 R和 RStudio

1.1 R和 RStudio 简介

R是使用广泛的统计计算和绘图分析软件,基于S语言编写,20世纪90年代初,由Ross Ihaka 和 Robert Gentleman 共同编写,2000年发行1.0.0版本。

RStudio是R语言的集成开发环境(IDE),RStudio之于R,相当于Pycharm之于python。RStudio是开源项目。

为什么要使用R :

  • 强大的绘图功能,能轻松绘制你想要的任何图像

  • 免费,开源

  • 强大的技术社区支持

R Markdown用来从 R 中创建文档和网页,Shiny 则是使用 R 创建交互式应用程序。

Style guide · Advanced R.

1.2 RStudio 界面介绍

左上:代码编辑栏。用于编辑代码,点击 run 即可运行。

左下:命令控制台,代码运行后,实时显示结果,如果出错,会进行报错。

右上:显示自定义的对象。

右下:查看文件、显示图像、获取包、获取帮助。

四个界面的大小可以自由拖动。

img

R具有庞大的生态,你在学习和使用R中遇到的问题,都可以通过help获取帮助。你可以点击上方的R help,跳转到右下角搜索想要的答案。

img

1.3 基本操作介绍

赋值

R 有一个最基本的概念——赋值,即把数据、表格等,赋予给一个新的变量,在R中赋值符号为 <-。比如:

1
2
3
4
x <- 2+3*6
y <- x
x = 56
y

输出结果为:

1
[1] 20

创建和保存文件

@todo

代码执行

使用Ctrl+Enter (command+return)执行本句代码,Ctrl+Shift+Enter (command+shift+return)执行文件中所有代码。

分隔符

当代码很长时,可以通过Ctrl (command) + shift + R插入像上面foo, bar风格符,增加代码可读性。

2. 向量(vector)

2.1 向量使用

对变量赋值,是R中的基本操作。赋值用符号<-,多个元素赋值可以使用c() (concatenate)函数.

1
2
x <- 5
num <- c(1, 4, 6, 19)

输出结果:

1
2
> nums
[1] 1 4 6 19

查看向量长度:

1
2
num <- c(1, 4, 6, 19)
length(num)

输出结果:

1
[1] 4

多个向量合并:

1
2
3
4
5
6
fruit_1 <- c("Apple","Banana","Carambola')
fruit_2 <- c("Durian","Haw","Lemon")

fruits <- c(fruit_1, fruit_2, c("Papaya","Persimmon","Strawberry"))

fruits

输出结果为:

1
2
3
> fruits
[1] "Apple" "Banana" "Carambola" "Durian" "Haw"
[6] "Lemon" "Papaya" "Persimmon" "Strawberry"

2.2 从列表中提取需要的元素

和python一样,R也可以提取需要的元素,但和python不一样的是,R从第一个开始:

看下面一个列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fruits <- c("Apple", "Banana", "Carambola", "Durian", "Haw", "Lemon" , "Papaya" ,  "Persimmon", "Strawberry")

fruits[3] # 提取第三个

fruits[c(2,5,7)] # 提取第2、5、7个

fruits[-c(2,5,7)] # 提取除了第2、5、7个的元素

fruits[c(2,5,7)] <- c("ON", "UP", "DOWN") # 第2,5,7个重新赋值

fruits[c(2:6)] # 提取第2,3,4,5,6个,包含第2个

fruits[2:6] # 提取第2,3,4,5,6个,包含第2个

fruits

运行结果分别是(注:上面代码必须单独运行,才能得到下面的结果,否则只会显示最后一个)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> fruits[3] # 提取第三个
[1] "Carambola"

> fruits[c(2,5,7)] # 提取第2、5、7个
[1] "Banana" "Haw" "Papaya"

> fruits[-c(2,5,7)] # 提取除了第2、5、7个的元素
[1] "Apple" "Carambola" "Durian" "Lemon" "Persimmon"
[6] "Strawberry"

fruits[c(2,5,7)] <- c("ON", "UP", "DOWN") # 第2,5,7个重新赋值
[1] "Apple" "ON" "Carambola" "Durian" "UP"
[6] "Lemon" "DOWN" "Persimmon" "Strawberry"

> fruits[c(2:6)] # 提取第2,3,4,5,6个,包含第2个
[1] "Banana" "Carambola" "Durian" "Haw" "Lemon"

> fruits[2:6] # 提取第2,3,4,5,6个
[1] "Banana" "Carambola" "Durian" "Haw" "Lemon"

2.3 生成器

2.3.1 元素重复

重复某个元素,基本格式如下:

(以下代码,上面是输入,下方为输出结果)

1
2
> rep(2, 3) # 把2重复3次;或rep(2, times = 3)
[1] 2 2 2

在此基础上,可以延展很多变体:

1
2
3
4
5
6
7
8
9
10
11
> rep(c(1,2,3,4), 4) # 把1,2,3,4重复4次
[1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
> rep(c(1:10), 2) # 1-10重复10次
[1] 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10
> rep(c(1, 2, 3), each = 3) # 把1, 2,3各重复4遍
[1] 1 1 1 2 2 2 3 3 3
> rep(c(1, 2, 3), c(3, 2, 0)) # 把1, 2, 3分别重复3, 2, 0遍
[1] 1 1 1 2 2
rep(8:15, rep(1:5, rep(1:2, 2:3))) # 把8(含)-15(含)分别重复1、2、3、3、4、4、5、5遍。注意每个元素与重复次数要对应,如8-15有8个元素,rep(1:5, rep(1:2, 2:3))也必须是8个原色
[1] 8 9 9 10 10 10 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 14 15 15 15
[26] 15 15

2.3.2 等差数列

1
2
3
4
> seq(0, 15, 2) # 其实是`seq(from = 0, to = 15, by = 2)`的简写,表示0-15中,等差序列为2
[1] 0 2 4 6 8 10 12 14
> seq(0, 20, length.out = 11) # 其实是`seq(from = 0, to = 20, length.out = 10`的简写。表示0-20中,按等差分成10个元素
[1] 0 2 4 6 8 10 12 14 16 18 20

2.3.3 随机数

常见的随机数用runif(n, min, max),n表示生成的随机数数量,min是最小值,max是最大值。默认min=0,max=1。

1
2
3
nums_1 <- runif(100000,1,100) # 随机生成10万个,1-100之间的随机数

hist(nums_1) # 画直方图

img

正态分布的随机数:

使用rnorm(n, mean, sd), 三个参数分别代表数量,平均值,标准差。默认mean为0,sd为1。

1
2
nums_1 <- rnorm(100000, 250, 20) # 生成10万个随机数,按照平均值为250,标准差为20,进行正态分布
hist(nums_1) # 画直方图

img

2.3.4 简单随机抽样

代码格式如下:

1
sample(balls, 20, replace = TRUE) # ball表示总体,20表示抽取的数量, replace = TRUE表示抽取后放回,FALSE表示抽取后不放回(可不写)

从10个球中随机抽取8个,每次抽取放回:

1
2
3
4
> balls <- letters[1:10]
> sample(balls, 8, replace = TRUE)

[1] "i" "g" "d" "c" "g" "i" "b" "c"

2.4 向量的排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> x <- c(10, 45, 2, 8, 12)

> sort(x) # 从小到大排序
[1] 2 8 10 12 45

> x[order(x)] # 从小到大排序
[1] 2 8 10 12 45

> order(x) # 返回每个元素从小到大对应的排序,如10是第三小的元素,返回值为3
[1] 3 4 1 5 2

> rev(sort(x)) # 从大到小排序
[1] 45 12 10 8 2

> rank(x) # 返回值为每个数值对应的排名
[1] 3 5 1 2 4

> rev(x) # 表示向量翻转
[1] 12 8 2 45 10

2.5 向量的集合运算

交集用intersect(x, y),并集用union(x, y),补集用setdiff(x, y)。作为集合是否相等,用setequal(x, y),确定元素是否是集合的某个元素用is.element(x, y),等价于x %in% y.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> x <- c(1:15)
> y <- c(10:25, 5)

> intersect(x,y) # 求交集
[1] 5 10 11 12 13 14 15

> union(x, y) #求并集
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
[21] 21 22 23 24 25

> setdiff(x, y) #求补集,即不在集合y中的元素
[1] 1 2 3 4 6 7 8 9

> setequal(x, y) # 是否相等
[1] FALSE

> is.element(x, y) #确定x是否是y中的元素
[1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
[11] TRUE TRUE TRUE TRUE TRUE

3. 数据和列表

3.1 数据类型及基本运算

3.1.1 数据类型

常见数据类型如下

类型 含义与说明 例子
numeric 浮点数向量 2, 3.14, sqrt(5)
integer 整数向量 1L,3L,5L
character 字符向量;需被引号包围 “@”, “34”, “文本”
logical 逻辑向量 TRUE, FALSE, NA
complex 复数向量 3+5i, i, 4+i

数据基本操作如下:

1
2
3
4
5
6
7
8
> class(3) # 查询数据类型
[1] "numeric"

> is.numeric(6) # 判断属于哪一种数据类型,TRUE则为正确
[1] TRUE

> as.numeric(6) # 强制转换为另一种数据类型
[1] 6

3.1.2 数据运算

符号 描述
+
-
*
/ 除以
^或** 乘幂
%/% 求整数商,比如7%/%3=2=2
%% 求余数,比如7%%3=1

3.1.3 常见的数据运算

e^x和logx(y)函数

1
2
exp(1) # e^x函数
log(100,10) # log(x,y),以y为底x的函数

保留数字位数

1
2
3
4
5
> signif(12.3456789, 4) # 保留4位数,注意是总共保留4位数,不是保留小数点后面4位
[1] 12.35

> round(12.3456789, 3) # 保留3位小数
[1] 12.346

3.1.4 R 中自带的常见函数

img

资料来源:2.3 数学表达和运算 | R与tidyverse——数据分析入门

3.2 列表

3.2.1 列表基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> list(1, 2, 4, NA, 3L, "de")

[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 4

[[4]]
[1] NA

[[5]]
[1] 3

[[6]]
[1] "de"

3.2.2 合并与拆开

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
> c(list(1, 2), list(3, 4, list(5,6))) # 使用c来合并列表
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

[[4]]
[1] 4

[[5]]
[[5]][[1]]
[1] 5

[[5]][[2]]
[1] 6
> unlist(list(1, list(2, list(3, 4)), list(5, 6), 7, 8, 9)) # 一直拆解到无列表
[1] 1 2 3 4 5 6 7 8 9

> unlist(list(1, list(2, list("a", 4)), list(5, TRUE), 7L, 8, 9+0i))
[1] "1" "2" "a" "4" "5" "TRUE" "7" "8" "9+0i"

# unlist(list(A, B)等同于c(A, B)

3.3 矩阵(matrix)和数组(array)

创建5行8列的数组:

1
2
3
A <- 1:40
dim(A) <- c(5,8)
A

输出结果:

1
2
3
4
5
6
  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 6 11 16 21 26 31 36
[2,] 2 7 12 17 22 27 32 37
[3,] 3 8 13 18 23 28 33 38
[4,] 4 9 14 19 24 29 34 39
[5,] 5 10 15 20 25 30 35 40

索引行列数据

1
2
3
4
5
6
7
8
> A[5,3] # 第5行第3列数据
[1] 15

> A[5, ] # 第5行全部数据
[1] 5 10 15 20 25 30 35 40

> A[, 7] # 第7列全部数据
[1] 31 32 33 34 35

创建2行8列的3个数组:

1
2
3
A <- 1:48
dim(A) <- c(2, 8, 3)
A

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
, , 1

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 3 5 7 9 11 13 15
[2,] 2 4 6 8 10 12 14 16

, , 2

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 17 19 21 23 25 27 29 31
[2,] 18 20 22 24 26 28 30 32

, , 3

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 33 35 37 39 41 43 45 47
[2,] 34 36 38 40 42 44 46 48

接下来使用**dimnames()**为每个行、列和每个列表命名

1
2
3
4
5
6
7
8
A <- 1:48
dim(A) <- c(2, 8, 3)

dimnames(A) <- list(paste("行数.", 1:2), # 行命名
c("列1", "列2", "列3", "列4", "列5", "列6", "列7", "列8"), # 列命名
c("表1", "表2", "表3")) # 表头命名

A

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
, , 表1

列1 列2 列3 列4 列5 列6 列7 列8
行数. 1 1 3 5 7 9 11 13 15
行数. 2 2 4 6 8 10 12 14 16

, , 表2

列1 列2 列3 列4 列5 列6 列7 列8
行数. 1 17 19 21 23 25 27 29 31
行数. 2 18 20 22 24 26 28 30 32

, , 表3

列1 列2 列3 列4 列5 列6 列7 列8
行数. 1 33 35 37 39 41 43 45 47
行数. 2 34 36 38 40 42 44 46 48

3.4 循环

循环语句的基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(var in seq) {
expr
}
m <- 1:100 # 产生一个[1,2,3,...,99,100] # 从1-100依次产生整数

n <- vector("numeric")
for (i in m) {
if (i %% 2 == 0) { # 如果i是偶数
n <- append(n, i^2) # 那么n为i的平方
} else if (i == 51) { # 当i等于51,则结束
break
}
}

n

输出结果:

1
2
 [1]    4   16   36   64  100  144  196  256  324  400  484  576  676  784  900
[16] 1024 1156 1296 1444 1600 1764 1936 2116 2304 2500

while循环:

当条件满足cond,重复循环expr。

1
2
3
while (cond) {
expr
}

重复执行使用repeat,直到使用break打断

1
2
3
4
5
6
7
8
9
10
11
repeat {
expr
}
i < 1
repeat {
print(i)
i = i + 1
if (i == 100) {
break
}
}

for 和 while 区别:

  • while 适用于不知道要运行多少次

  • 知道结束循环的条件

4. 函数

4.1 函数基本操作

1
2
3
4
FuncName <- function (arglist) {
expr
return(value)
}

举例

1
2
3
4
5
6
7
8
9
10
11
grade <- function(i, k){
if(k <= 100) {
k = i^2
return(k)
}
else {
break
}
}

grade(i<-1:100, 10)

输出结果:

1
2
3
4
5
6
7
8
9
10
> grade(i<-1:100, 10)
[1] 1 4 9 16 25 36 49 64 81 100 121 144
[13] 169 196 225 256 289 324 361 400 441 484 529 576
[25] 625 676 729 784 841 900 961 1024 1089 1156 1225 1296
[37] 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304
[49] 2401 2500 2601 2704 2809 2916 3025 3136 3249 3364 3481 3600
[61] 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041 5184
[73] 5329 5476 5625 5776 5929 6084 6241 6400 6561 6724 6889 7056
[85] 7225 7396 7569 7744 7921 8100 8281 8464 8649 8836 9025 9216
[97] 9409 9604 9801 10000

遇到层层函数嵌套的情况**h(g(f**(x))),借助% > % :

1
2
3
4
x %>% 
f() %>%
g() %>%
h()

5. tibble

tibble用来替换data.frame的表格型数据结构,tibble是tidyverse的一部分,读写速度更快。

1
2
library(didyverse)
mpg # 默认显示前10行

img

(图片来源:https://tshi.page/r-and-tidyverse-book/tibble-view.html)

基本操作:

1
2
3
view(mpg) # 查看所有数据
head(mpg, 8) # 开头前8行
tail(mpg) # 最后8行

5.1 创建

5.1.1 创建

直接在向量中赋值:

1
2
3
4
5
6
7
8
library(tibble)

my_tibble_1 <- tibble(
nums = c("one", "two", "three"), # 列1
chars_1 = c("数1", "数2", "数3"), # 列2
chaars_2 = c("数4", "数5", "数6") # 列3
)
my_tibble_1

输出结果为:

1
2
3
4
5
6
# A tibble: 3 × 3
nums chars_1 chaars_2
<chr> <chr> <chr>
1 one 数1 数4
2 two 数2 数5
3 three 数3 数6

也可以通过向量创建:

1
2
3
4
5
6
7
x <- c("one", "two", "three")
y <- c("数1", "数2", "数3")
z <- c("数4", "数5", "数6")

my_tibble_1 <- tibble(nums = x, chars_1 = y, chars_2 = z)

my_tibble_1

输出结果如下,与第一种方法一样:

1
2
3
4
5
6
# A tibble: 3 × 3
nums chars_1 chars_2
<chr> <chr> <chr>
1 one 数1 数4
2 two 数2 数5
3 three 数3 数6

5.1.2 新增

1
2
3
4
chars_2 <- mutate(my_tibble_1, 
chars_3 = c("数7", "数8", "数9")

my_tibble_1

5.2 抓取行列

5.2.1 抓取列

从整个列表中抓取需要所需的列,可以使用下面三种方法:

1
2
3
4
5
6
7
8
# 方法1:通过变量名称抓取
my_tibble_1[["chars_1"]]

# 方法2:使用$
my_tibble_1$chars_1

# 方法3:使用索引
my_tibble_1[[2]]

如果要抓取多列,则可以使用select:

1
2
3
4
5
6
7
8
9
10
11
library(dplyr)

x <- c("one", "two", "three")
y <- c("数1", "数2", "数3")
z <- c("数4", "数5", "数6")

my_tibble_1 <- tibble(nums = x, chars_1 = y, chars_2 = z)

shuju <- select(my_tibble_1, 1, 3) # 提取第一列,第三列,也可以使用select(my_tibble_1, -2)

shuju

运行结果如下:

1
2
3
4
5
6
# A tibble: 3 × 2
nums chars_2
<chr> <chr>
1 one 数4
2 two 数5
3 three 数6

5.2.2 抓取行

抓取行的方法和抓取列的方法一样,把select函数换成slice()函数.

1
2
3
4
5
6
7
8
9
10
11
library(dplyr)

x <- c("one", "two", "three")
y <- c("数1", "数2", "数3")
z <- c("数4", "数5", "数6")

my_tibble_1 <- tibble(nums = x, chars_1 = y, chars_2 = z)

shuju <- slice(my_tibble_1, 1, 3) # 提取第一行,第三行,也可以使用slice(my_tibble_1, -2)

shuju

结果如下:

1
2
3
4
5
# A tibble: 2 × 3
nums chars_1 chars_2
<chr> <chr> <chr>
1 one 数1 数4
2 three 数3 数6

抓取满足某些特定条件的行,使用filter():

1
2
3
4
5
6
7
8
9
10
11
library(dplyr)

x <- 1:6
y <- 4:9
z <- 5:10

my_tibble_1 <- tibble(nums = x, chars_1 = y, chars_2 = z)

shuju <- filter(my_tibble_1, chars_2>=3 & chars_2 <= 6) # 提取chars_2列 满足数字大于等于3小于等于6的元素

shuju

结果如下:

1
2
3
4
5
# A tibble: 2 × 3
nums chars_1 chars_2
<int> <int> <int>
1 1 4 5
2 2 5 6

5.2.3 排序

使用arrange

排序:

1
2
arrange(my_tibble_1, chars_2) # 从小到大排列
arrange(my_tibble_1, -chars_2) # 从大到小排列

重命名变量

1
my_tibble <- dplyr::rename(my_tibble_1, 列2 = chars_2) # 把chars_2命名为 列2

5.2.4 汇总统计

使用summarize

1
summary_temp <- summarize(my_tibble_1, mean(chars_1), sd(chars_1))
  • mean(): 平均值

  • sd(): 标准差,它是价差的衡量标准

  • min()max():分别为最小值和最大值

  • IQR(): 四分位距

  • sum(): 多个数字相加的总数

  • n(): 每组中的行数

5.2.5 分组

使用groub_by

1
2
3
4
5
summary_monthly_temp <- weather %>% 
group_by(month) %>%
summarize(mean = mean(temp, na.rm = TRUE),
std_dev = sd(temp, na.rm = TRUE))
summary_monthly_temp

6. R 包

6.1 包的安装和卸载

R 包是什么?我们可以把RStudio理解为一部手机,R 包则是一个个的APP,把能实现特定功能的程序“打包”在一起,当你调用包时,就可以实现想要的功能。

包的安装有两种方法。

第一种:找到顶部菜单栏Tools—>Install Packages—>输入包的名称,完成安装

第二种:在代码运行区输入

1
install.packages('包的名称')

安装成功后,显示如下:

img

包的更新:

更新:update.packages()

包的卸载:remove.packages()

6.2 包的使用

在使用包时,需要使用如下代码加载包:

1
library('包的名称')

如果有多个包,每一个包的加载都输入上面的加载语法麻烦的话,可以使用下面语法,加载多个包,读取成功,会返回TRUE。

1
library(c('包1', '包2', '包3'), require, c = T)

当载入dplyr时,我们发现:

1
2
3
4
5
6
7
8
9
载入程辑包:‘dplyr’

The following objects are masked from ‘package:stats’:

filter, lag

The following objects are masked from ‘package:base’:

intersect, setdiff, setequal, union

为什么会这样?因为R自带了stats、base的包,现在使用的dplyr有同名的 filter(), lag(),intersect(),setdiff(),setequal(), union(),把自带的覆盖了。此时,程序会以最后(近)的包为对象读取。当然,你也可以使用packageName::object调取,先把包名称写出来。不过这种方法,应该不常用。

在R包中,最常用的包有下面四个:

1
2
3
4
library(ggplot2)
library(dplyr)
library(readr)
library(tidyr)

ggplot2用于数据可视化,dplyr用于数据整理,readr用于将电子表格数据导入 R,tidyr用于转置数据。

而这四个R包,可以通过tidyvers包一并加载出来。

1
2
3
4
5
6
7
8
> library(tidyverse)
── Attaching packages ────────────────────────────────────── tidyverse 1.3.1 ──
✔ tibble 3.1.7 ✔ dplyr 1.0.9
✔ tidyr 1.2.0 ✔ stringr 1.4.0
✔ purrr 0.3.4 ✔ forcats 0.5.1
── Conflicts ───────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()

7. 数据导入和整理

7.1 数据导入

1
2
3
library(readr)
dem_score <- read_csv("https://moderndive.com/data/dem_score.csv")
dem_score

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# A tibble: 96 × 10
country `1952` `1957` `1962` `1967` `1972` `1977` `1982` `1987` `1992`
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Albania -9 -9 -9 -9 -9 -9 -9 -9 5
2 Argentina -9 -1 -1 -9 -9 -9 -8 8 7
3 Armenia -9 -7 -7 -7 -7 -7 -7 -7 7
4 Australia 10 10 10 10 10 10 10 10 10
5 Austria 10 10 10 10 10 10 10 10 10
6 Azerbaijan -9 -7 -7 -7 -7 -7 -7 -7 1
7 Belarus -9 -7 -7 -7 -7 -7 -7 -7 7
8 Belgium 10 10 10 10 10 10 10 10 10
9 Bhutan -10 -10 -10 -10 -10 -10 -10 -10 -10
10 Bolivia -4 -3 -3 -4 -7 -7 8 9 9
# … with 86 more rows

可以看到,变量名两侧加上了引号,那是因为默认情况下,R 中的变量名不允许以数字开头,也不允许包含空格。

导入excel文件方法类似,可以使用路径File--> Import Dateset --> From Excel操作界面如下,观察右下角的代码,也可以使用代码导入。

img

7.2 数据清理

每一个变量为一列,每一个观察为一行,每种类型的数据形成一个单独的表格。

观察7.1中的数据,country 是变量,应该变成列,时间应该变成行,可以使用下面的代码实现:

1
2
3
4
5
6
guat_dem_tidy <- guat_dem %>% 
pivot_longer(names_to = "year", # names_to 为把原来数据框中的行变为列
values_to = "democracy_score", # values_to 字符串,创建新的列名称
cols = -country, # 为不想整理的
names_transform = list(year = as.integer)) # 设置变量的数值类型
guat_dem_tidy

实际运用中,拿到的数据往往存在缺失值、数据出错等情况,我们称之为脏数据,包括:

  • 缺失值:R中有NA表示,可以使用is.na()判断是否存在缺失值。处理方法
    - 删除法:na.omit(),移除所有含有缺失行等列
    - 替换法:使用中位数和众数替换

  • 异常值

  • 重复值

7.3 数据挖掘相关包

img

8. 回归分析

8.1 描述性数据分析

数据分析有三种类别:描述性数据分析、预测性数据分析、规范性数据分析。

  • 描述性数据分析:描述数据是什么。常见指标包括平均数、中位数、众数、四分位数等。

  • 预测性数据分析:从数据中预测。

  • 规范性数据分析:从数据中得到判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
library(tidyverse)

library(readr)
dem_score <- read_csv("https://moderndive.com/data/dem_score.csv")

guat_dem_tidy <- dem_score %>%
pivot_longer(names_to = "year", # names_to 为把原来数据框中的行变为列
values_to = "democracy_score", # values_to 字符串,创建新的列名称
cols = -country, # 为不想整理的
names_transform = list(year = as.integer)) # 设置变量的数值类型

guat_dem_tidy %>% summarize(
year_mean = mean(year), democracy_score_mean = mean(democracy_score),
year_median = median(year)
)

结果如下:

1
2
3
 year_mean democracy_score_mean year_median
<dbl> <dbl> <dbl>
1 1972 -0.826 1972

次数可以使用skim(),一次性计算:

  • missing:缺失值的数量

  • complete:非缺失值或完整值的数量

  • n:值的总数

  • mean: 平均值

  • sd: 标准差

  • p0:最小值

  • p25:1/4分位数

  • p50:1/2分位数

  • p75:3/4分位数

  • p100:最大值

计算相关系数:

1
2
evals_ch5 %>% 
get_correlation(formula = score ~ bty_avg)

8.2 一元线性回归

描述一个自变量和一个因变量之间的关系。

1
2
3
4
5
x <- c(1, 12, 89, 28, 13, 93, 92, 9, 34)
y <- c(34, 12, 13, 56, 89, 1, 9, 23, 20)

relation <- lm(y ~ x)
relation

得出x y 的相关系数:

1
2
3
Coefficients:
(Intercept) x
44.6890 -0.3914

8.3 多元线性回归

8.4 R语言分类及预测算法函数

使用R进行数据挖掘时,分类和预测占很大比重,涵盖多个算法模块。主要的算法模型包含神经

9. 抽样

例1:从一个碗中随机抽取50个小球,计算抽取到红色小球的概率。

1
2
3
4
5
6
7
8
9
library(tidyverse)
library(moderndive)

tactile_prop_red

ggplot(tactile_prop_red, aes(x = prop_red)) +
geom_histogram(binwidth = 0.05, boundary = 0.4, color = "white") +
labs(x = "Proportion of 50 balls that were red",
title = "Distribution of 33 proportions red")

img

例2:从1000个球中随机抽取25个,计算是红色球的概率,并且绘制成条形图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
library(tidyverse)
library(moderndive)

bowl

# 1.a) Virtually use shovel 1000 times
virtual_samples_25 <- bowl %>%
rep_sample_n(size = 25, reps = 1000)

# 1.b) Compute resulting 1000 replicates of proportion red
virtual_prop_red_25 <- virtual_samples_25 %>%
group_by(replicate) %>%
summarize(red = sum(color == "red")) %>%
mutate(prop_red = red / 25)

# 1.c) Plot distribution via a histogram
ggplot(virtual_prop_red_25, aes(x = prop_red)) +
geom_histogram(binwidth = 0.05, boundary = 0.4, color = "white") +
labs(x = "Proportion of 25 balls that were red", title = "25")

10. 假设检验、置信区间

@todo

11. 数据可视化

11.1 ggplot介绍

ggplot是用于数据可视化的包。

基本操作语法为:

1
ggplot(data = NULL, mapping = aes(), ..., environment = parent.frame())

有3个部分组成:

  • data:数据集。

  • geom: 几何对象,可以在图中观察到的对象类型。例如:点、线和条。

  • aes:描述几何对象,如x/y 位置、颜色、形状和大小。

基本图形

  • 散点图geom_point()

  • 折线图geom_line()

  • 箱线图通过geom_boxplot()

  • 直方图通过gom_histogram()

  • 通过条形图geom_bar()geom_col()

示例:

1
2
3
4
5
library(nycflights13)
library(ggplot2)

ggplot(data = alaska_flights, mapping = aes(x = dep_delay, y = arr_delay)) +
geom_point() # 散点图

img

12. 实战案例:西雅图房价预测

@todo

感谢

在学习过程中,除了参考官方文档,主要参考了R与tidyverse——数据分析入门 内容,非常感谢!

ChangeLog

20220805 优化案例

20220618 完成初稿