Bootstrap

R语言基础教程

常用机为Mac,但window也是一样的哦(有差别的地方有讲解)

R语言和其他语言差别很大哦,里面有很多基础基础基础的内容,包括介绍数据结构。但语法还是和其他语言一样哦,比如循环、判断。有基础食用更香!

本章单纯为R基础,R的应用与高级操作不属于本章内容

1. R的初入了解

R常被用于做数据分析,通过大数据计算预期的结果

  1. 什么是数据?数据就是一个具有一定属性的事物,含义很广;
  2. 为什么要做数据分析?通过分析数据得到的结果指导决策。

过程:

  1. 数据采集;
  2. 数据存储;
  3. 数据统计:使用统计方法,带有目的分析统计数据;
  4. 数据挖掘:从大量数据从算法挖掘出有用的信息;
  5. 数据可视化:将数字数据转变为易于理解的数据。

然后来稍微的介绍一下数据挖掘:

  1. 要分析与某事物相关的所有数据,而不是取少量的样本;
  2. 我们可以介绍数据的多与杂乱,不追求极度的精确性;
  3. 更关注与事物的相互关系,而不是因果关系(事物并非完全由因果关系而被联系在一起);

再来讲一下数据可视化:

将数字结果用图展示出来

因为数据是给机器看的,数据可视化是给人看的

了解R语言:

R的优点:和python一样,开源,方法多,拓展性强

R的作用:计算、算法、绘图、编程

R的缺点:什么都能做但复杂,包太多难学

2. 基础R命令学习

我先给大家来罗列一些常用的系统命令吧,这个也挺简单,就不放图啦~

2.1. 一些基本的操作指令

函数名作用
list.files() / dir()查看当前目录下的文件
getwd() / setwd()查看/设置默认工作区位置
save.image()保存数据
q()退出

2.2. 对R包的操作

我们平常会对R包进行增删改查的操作,我们可以看一下我们有哪些操作:

函数名作用
install.package(“name”) / remove.package(“name”) / update.package(“name”)安装/卸载/更新name包的内容(更新可以不带参数)
library() / library(name) / library(help=“name”)查看系统中已有的包 / 判断name包是否存在 / 查看包的信息
help(package=“name”)打开name包的帮助文档
ls(“package:name”)查看某个包中全部的函数
data(package=“name”)查看name包中的数据集
require(name) / detach(name)加载/关闭名为name的包

2.3. 针对对象的操作

我们在装好了R的包之后,自然常用的就是对象了,然后下面我们罗列一些针对这些对象的增删改查的指令:

函数名作用
object<-0 / object<<-0为object赋值为0 / 强制赋值,可以强制给全局变量赋值
str(object)查看object变量的详细内容
rm(object)删除object变量(可以使用rm(list=ls())的方法删除所有变量)
ls() / ls.str() / ls(object)查看工作区内的所有变量 / 可以看到工作区中每个变量的详细内容 / 判断object是否存在 /

2.4. 帮助指令

我们在不会使用包、函数的时候,经常会借助帮助指令查看帮助,得以了解,在这里我也列出几个帮助指令

函数名作用
help(package=name)打开name包的帮助文档
help(funtion)打开funtion函数的帮助文档
?funtion打开funtion函数的帮助文档
args(funtion)直接在终端中输出函数应输入的参数
emample(“function”)会在终端中打印出使用案例,
如果是绘图函数也会给出绘图案例
demo(function)可以返回一些绘制的阳历图
vignette(“package”)部分package有这个更规范的开发文档
??package即使不加载包可以搜索到相应的文档
help.search(“package”)在本地搜索package包的文档
apropos(“key”) / apropos(“key”, mod=“function”)可以搜索含有key关键字的内容 / 可以限定搜索的结果为函数
RSiteSearch(“key”)用默认浏览器在官网搜索key关键字

2.5. 数据集

我们经常在学习的时候会用到很多的数据,无论是矩阵数据还是列表数据,等等。一遍又一遍的自己创造数据比较浪费时间,所以R内部含有许多数据集,如美国每个州的名字,每个地方的信息,一些汽车的信息,表格数据,等等等等。我们可以方便的使用这些。

我们在命令行中敲两行帮助代码可以查看到我们有的数据集:

> help(package="datasets")
> data()

3. R的数据结构

R主要分成四大数据类型:

  • 数值型:数学计算;
  • 字符串型:连接转换提取;
  • 逻辑型:T/F;
  • 日期型。

R主要的数据结构:

  • 向量、标量;
  • 矩阵、数组;
  • 列表;
  • 数据框;
  • 因子;
  • 时间序列。

3.1. 向量(Vector)

3.1.1. 创建向量

R语言中的向量,是构成其他数据结构的基础,R中的向量,更像其他语言中的数组。所以我们可以把向量认为是用于存储数据型、字符型、逻辑型数据的一维数组。我们统一用函数c来创建向量,如:

> c(1, 2, 3, 4, 5)
> c('a', 'b', 'c', 'd', 'e')
> c(T, F, T, F, T)

同时要注意,向量中每个数据不能出现不同的数据类型,能转换的会自动帮你转换,不能转换的会直接报错(为啥不能不同呢?因为向量是用来计算的:一种类型才能计算咯),总的来说,优先级是:字符串型>数值型>逻辑型(ps:R中的逻辑型为T/F/TRUE/FALSE,必为全大写)。

我们还能用seq函数构造向量,seq函数的优点是可以控制等差差值:

> seq(1, 100, 2) # seq(初值,终值,步长)
[1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49
[26] 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99

构造向量的时候我们经常也会用到一些重复的操作(输入多个一样的数),这个时候我们就可以用到rep函数了。rep函数可以将一个对象重复多次,然后我们可以将这个结果赋值到对象中。

> x <- rep('a', 5)
> x
[1] "a" "a" "a" "a" "a"

我们可以明显的看出来我们完成了自己的目的。

当然,我们也可以进行这样的操作:

> x <- c(1,2,3,4,5)
> rep(x, 5) # 将向量复制五次
[1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2
[18] 3 4 5 1 2 3 4 5

也可以进行这样的操作:

> x <- c(1,2,3,4,5)
> rep(x, each=5) # 将每个元素复制五次
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4
[18] 4 4 4 5 5 5 5 5

还能这样:

> x <- c(1,2,3,4,5)
> rep(x, each=5, time=2) # 不仅每个复制五次,害复制两遍
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4
[18] 4 4 4 5 5 5 5 5 1 1 1 1 1 2 2 2 2
[35] 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5

小补充:我们咋查看数据类型呢?我们可以通过class函数或mode函数查看向量的数据类型:

> class(x)
[1] "character"
> mode(x)
[1] "character"

3.1.2. 顺便讲一下标量

讲了这么多向量的内容,那什么是标量呢?标量太好理解了,其实就是单个的数据呗,比如 a <- 0a <- Fa <- 'str'

3.1.3. 向量索引

向量和基础语言不一样,起点是从1开始的:

> x <- 1:10
> x
[1]  1  2  3  4  5  6  7  8  9 10
> x[1] # 查找第一个
[1] 1
> x[0] # 没有第零个
integer(0)
> x[c(2, 5, 9)] # 多找几个
[1] 2 5 9
> x[5:7]
[1] 5 6 7

从上面我们也能看出来,正数就是索引,那负数是什么呢?其实索引的时候使用负号,我一般不称ta为负号,而是减号。因为这是代表删除元素的作用:

> x <- 1:10
> x
[1]  1  2  3  4  5  6  7  8  9 10
> x[-3] # 去除第三个元素
[1]  1  2  4  5  6  7  8  9 10
> x[c(-1,-3)] # 也可以删多个
[1]  2  4  5  6  7  8  9 10
> x[-1:-3]
[1]  4  5  6  7  8  9 10

所以我们也能看出来,正负数不能同时用的:

> x[c(-1,5)]
Error in x[c(-1, 5)] : only 0's may be mixed with negative subscripts

或者还能用逻辑值这样玩:

> x[c(T,T,T,F,F,F,T,T,T,F)] # 对应值为真就输出
[1] 1 2 3 7 8 9
> x[c(T, F)] # 自动拓展成TFTFTFTFTF
[1] 1 3 5 7 9
> x[c(T, T, F)] # 不是倍数也一样拓展TTFTTFTTFT
[1]  1  2  4  5  7  8 10

接下来,讲一个新的东西,可以用于判断一个元素是否在向量中,学过python的可能知道有in这个东西,R也差不多哦:

> x <- c('a', 'b', 'c', 'd', 'e')
> x
[1] "a" "b" "c" "d" "e"
> 'a' %in% x # 判断a在不在
[1] TRUE
> c('a', 'b') %in% x # 多判断几个,返回多个结果
[1] TRUE TRUE

################
# 我们再玩点花的 #
################

> x[x %in% c('b', 'c', 'f')] # 知道我咋完成的么
[1] "b" "c"

我们看看上面这个咋完成的?我们很简单就能看出来是输出x存在于后面数组中的元素,其实我们要看懂这个不难,把代码拆解开来看:

> x %in% c('b', 'c', 'f') # 分别判断x中的所有元素是否在后面的向量中
[1] FALSE  TRUE  TRUE FALSE FALSE
> x[c(F,T,T,F,F)] # 将判断结果用逻辑值的方法输出
[1] "b" "c"

接下来我们讲讲给向量中的元素取名字,其实取名字也就是做一个索引的字典而已,那我们怎么取名字呢?

> x <- 1:5
> x
[1] 1 2 3 4 5
> names(x) <- c('a', 'b', 'c', 'd', 'e') # 取名字
> x
a b c d e 
1 2 3 4 5 

取完名字我们就可以这样玩了:

> x['c']
c 
3

还有,我们怎么在已有的向量后面追加元素呢?这个时候其实可以用到我们之前的知识,就是构造向量的知识:

> x <- 1:5
> x
[1] 1 2 3 4 5
> c(x, 6:9) # 利用创造向量的函数合并了向量
[1] 1 2 3 4 5 6 7 8 9

除了在后面追加还有插入元素(往后插):

> x <- 1:5
> x
[1] 1 2 3 4 5
> append(x, 2.5, 2) # append(向量,元素,第几个位置后面)
[1] 1.0 2.0 2.5 3.0 4.0 5.0

讲了追加,插入,还有删除,删除我一开始讲了,我就不讲了。

加一个which函数,用于查找索引值用的:

> x <- 9:1
> x
[1] 9 8 7 6 5 4 3 2 1
> which.max(x) # 查找最大值位置
[1] 1
> which.min(x) # 查找最小值位置
[1] 9
> which(x==2) # 查找为2的值的位置
[1] 8
> which(x>7) # 查找大于7的值的位置
[1] 1 2

其实从上面很容易发现,which是根据逻辑值的数组来确定的,也就是说我们也可以这样得到位置对应的值:

> x[which(x>7)]
[1] 9 8

3.1.4. 向量的运算

说到向量的运算,是不是想到了数学里面向量的运算?对的!这也就是我们使用向量的根本原因之一,我们的计算就是以向量的方式完成的。

我们来拿加法举例,其他语言是不是数据要所有数据相加,要循环遍历然后相加?但是R可以直接使用向量的操作,其他语言的相信你会的~~(我懒得写其他语言的代码了)~~:

> x <- c(1, 2, 3, 4, 5)
> y <- c(6, 7, 8, 9, 0)
> x * 2 + y
[1]  8 11 14 17 10

所以我们可以罗列出向量的四则运算:

> x
[1] 1 2 3 4 5
> y
[1]  6  7  8  9 10
> x + y # 加
[1]  7  9 11 13 15
> x * y # 乘
[1]  6 14 24 36 50
> y - x # 减
[1] 5 5 5 5 5
> y / x # 除
[1] 6.000000 3.500000 2.666667
[4] 2.250000 2.000000
> x ** y # 幂
[1]       1     128    6561  262144
[5] 9765625
> y %% x # 取余
[1] 0 1 2 1 0
> y %/% x # 整除
[1] 6 3 2 2 2

这个地方有一个小细节,这里和我们之前的逻辑值拓展一样,如果x只有两个数,y有8个数,也是可以拓展相加的,但是四则运算的要求就一定是倍数,不能是别的了:

> x
[1] 1 2
> y
[1] 1 2 3 4 5 6 7 8
> x + y
[1]  2  4  4  6  6  8  8 10
> x * y
[1]  1  4  3  8  5 12  7 16
> y - x
[1] 0 0 2 2 4 4 6 6
> y / x
[1] 1 1 3 2 5 3 7 4
> y ** x
[1]  1  4  3 16  5 36  7 64
> y %% x
[1] 0 0 0 0 0 0 0 0
> y %/% x
[1] 1 1 3 2 5 3 7 4

> x <- 1:3
> y / x # 修改后不是倍数(有警告,而且不能兼容所有版本)
[1] 1.0 1.0 1.0 4.0 2.5 2.0 7.0 4.0
Warning message:
In y/x : longer object length is not a multiple of shorter object length

向量判断相等也是使用==,而非=负号,因为=符号也有赋值的作用,结果当然还是一个逻辑值数组:

> x <- 1:5
> y <-  6:10
> x
[1] 1 2 3 4 5
> y
[1]  6  7  8  9 10
> x == y
[1] FALSE FALSE FALSE FALSE FALSE

向量中还有一些方便的运算,我们来看看:

> x <- 1:18
> x
[1]  1  2  3  4  5  6  7  8  9 10 11
[12] 12 13 14 15 16 17 18
> x[x>6 & x<12] # 选取满足条件的项
[1]  7  8  9 10 11
> x>6 & x<12 # 判断满足条件的项
[1] FALSE FALSE FALSE FALSE FALSE
[6] FALSE  TRUE  TRUE  TRUE  TRUE
[11]  TRUE FALSE FALSE FALSE FALSE
[16] FALSE FALSE FALSE
> y <- 1:3
> rep(y, 3:1) # 按照另一个向量中的每个数字复制n遍
[1] 1 1 1 2 2 3

我们再来看一些计算函数吧:

> x <- -5:5
> abs(x) # 绝对值
 [1] 5 4 3 2 1 0 1 2 3 4 5
> x = abs(x)
> sqrt(x) # 求平方根
 [1] 2.236068 2.000000 1.732051
 [4] 1.414214 1.000000 0.000000
 [7] 1.000000 1.414214 1.732051
[10] 2.000000 2.236068
> log(x) # 自然对数(当然可以换参数)
 [1] 1.6094379 1.3862944 1.0986123
 [4] 0.6931472 0.0000000      -Inf
 [7] 0.0000000 0.6931472 1.0986123
[10] 1.3862944 1.6094379
> exp(x) # 自然对数的幂
 [1] 148.413159  54.598150  20.085537
 [4]   7.389056   2.718282   1.000000
 [7]   2.718282   7.389056  20.085537
[10]  54.598150 148.413159
> x <- c(-2.4, -2.6, 2.4, 2.6)
> x
[1] -2.4 -2.6  2.4  2.6
> ceiling(x) # 向上取整
[1] -2 -2  3  3
> floor(x) # 想下取整
[1] -3 -3  2  2
> trunc(x) # 返回整数部分
[1] -2 -2  2  2
> round(x, 0) # 四舍五入,保留小数点后n位
[1] -2 -3  2  3
> signif(x, 1) # 四舍五入,保留有效数字
[1] -2 -3  2  3
> sin(x) # 正弦
[1] -0.6754632 -0.5155014  0.6754632
[4]  0.5155014
> cos(x) # 余弦
[1] -0.7373937 -0.8568888 -0.7373937
[4] -0.8568888
> sum(x) # 求和
[1] 0
> max(x) # 最大值
[1] 2.6
> min(x) # 最小值
[1] -2.6
> range(x) # 最大和最小值
[1] -2.6  2.6
> mean(x) # 平均值
[1] 0
> var(x) # 方差
[1] 8.346667
> sd(x) # 标准差
[1] 2.88906
> prod(x) # 连乘的积(全部相乘)
[1] 38.9376
> median(x) # 中位数
[1] 0
> quantile(x) # 分位数
   0%   25%   50%   75%  100% 
-2.60 -2.45  0.00  2.45  2.60 
> quantile(x, c(0.4, 0.5, 0.8)) # 自定义计算分位数
  40%   50%   80% 
-1.44  0.00  2.48 

3.2. 矩阵

向量是一维的,而矩阵是二维的,自然就有行和列,我们也把矩阵称作是有维数的向量。

例如我们有一些数据集就是矩阵:iris3鸢尾花数据集,state.x77美国50个州的8个指标。然后利用heatmap函数输入矩阵就可以得到热图,我们可以试试:

> heatmap(state.x77)

3.2.1. 创建矩阵

上面简单介绍了一些矩阵,接下来我们来看一下怎么创建一个矩阵

我们说到矩阵就是一个有纬度的向量,所以向量和矩阵之间当然是可以相互转换的,比如一个一维的向量,裁成n等份,不就变成一个矩阵了吗?我们一起来看一下:

> x <- 1:20
> x
 [1]  1  2  3  4  5  6  7  8  9 10 11
[12] 12 13 14 15 16 17 18 19 20
> mx <- matrix(x, 4, 5) # 将x拆分成四行五列
> mx
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> mx <- matrix(x, 4) # 只给行或列参数会自动补全为4*5
> mx
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> mx <- matrix(x, , 5)
> mx
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

但是这个是不是和想象中的有点不一样呢?对的,我们的数据是按列分布的(R语言中的默认情况就是按列分布),但我们很多时候需要的是按行分布,所以matrix还有第四个参数就是按行分布。

> mx <- matrix(1:20, 4, 5, T) # 第四个参数为TRUE表示按行分布
> mx
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
[3,]   11   12   13   14   15
[4,]   16   17   18   19   20

既然我们可以给向量中的每个数据命名,我们当然也可以给矩阵中的每行每列命名。我们来看一下命名方法:

> rname <- c('R1', 'R2', 'R3', 'R4')
> cname <- c('C1', 'C2', 'C3', 'C4', 'C5')
> rname
[1] "R1" "R2" "R3" "R4"
> cname
[1] "C1" "C2" "C3" "C4" "C5"
> dimnames(mx) <- list(rname, cname) # 给每行每列命名
> mx
   C1 C2 C3 C4 C5
R1  1  2  3  4  5
R2  6  7  8  9 10
R3 11 12 13 14 15
R4 16 17 18 19 20

我们一样是拆分开来看:

> mx <- matrix(1:20, 4, 5)
> mx
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> dimnames(mx) # 我们先来看一下dimname(mx)是啥,发现啥也没有
NULL
> class(dimnames(mx)) # 这个时候他也没有属性(但其实是纬度指标)
[1] "NULL"
> list(rname, cname) # 由行列名构成的指标
[[1]]
[1] "R1" "R2" "R3" "R4"

[[2]]
[1] "C1" "C2" "C3" "C4" "C5"

> dimnames(mx) <- list(rname, cname) # 给纬度向量命名
> dimnames(mx) # 现在纬度指标为列表了,并且为行、列两项
[[1]]
[1] "R1" "R2" "R3" "R4"

[[2]]
[1] "C1" "C2" "C3" "C4" "C5"
> mx
   C1 C2 C3 C4 C5
R1  1  5  9 13 17
R2  2  6 10 14 18
R3  3  7 11 15 19
R4  4  8 12 16 20

3.2.2. 构造数组(多维)

这里的数组和我们平常说的数组不一样,一般是指多纬度的数组,比如二维三维,我们可以先构建一个二维数组(也就是矩阵)来看一下:

> x <- 1:20
> dim(x) <- c(4, 5) # 将x变成二维的
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

可能有人说,这和matrix有什么不一样吗??这当然不一样,第一是用法不一样,第二是这个可以创造更高维度的数组。

什么叫用法不一样?是因为dim是直接对一个向量进行操作,改变ta的结构,而matrix是创造一个矩阵:

> x <- matrix(1:20, 4, 5) # 创造一个1:20的4*5的矩阵
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> y <- 1:20
> dim(y) <- c(4, 5) # 将y从一个一维向量变成矩阵
> y
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

什么叫更高维度的数组?是因为ta除了可以在一维向量和矩阵之间任意转换,更高维度也可以:

> y
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> dim(y) <- c(2, 2, 5) # 将y从一个矩阵变成一个三维数组
> y
, , 1

     [,1] [,2]
[1,]    1    3
[2,]    2    4

, , 2

     [,1] [,2]
[1,]    5    7
[2,]    6    8

, , 3

     [,1] [,2]
[1,]    9   11
[2,]   10   12

, , 4

     [,1] [,2]
[1,]   13   15
[2,]   14   16

, , 5

     [,1] [,2]
[1,]   17   19
[2,]   18   20

说到matrix可以创建矩阵,dim可以修改数组维度,那必然还有创造多维数组 的函数,那就是array函数:

> x <- array(1:20, c(4, 5)) # 创建二维数组
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> y <- array(1:9, c(3, 3, 3)) # 创建三维数组
> y
, , 1

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

, , 2

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

, , 3

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

> y <- array(1:9, c(3, 3, 3), dimnames = list(c('A1', 'A2', 'A3'), c('B1', 'B2', 'B3'), c('C1', 'C2', 'C3'))) # 还能给三个维度取名
> Y
Error: object 'Y' not found
> y
, , C1

   B1 B2 B3
A1  1  4  7
A2  2  5  8
A3  3  6  9

, , C2

   B1 B2 B3
A1  1  4  7
A2  2  5  8
A3  3  6  9

, , C3

   B1 B2 B3
A1  1  4  7
A2  2  5  8
A3  3  6  9

3.2.3. 矩阵的索引

索引也和向量中索引的方法很像,无非就是选取行列,删除行列,省略参数这样子的。

我们还是先来点基础的,选取行列:

> x <- matrix(1:20, 4, 5, T)
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
[3,]   11   12   13   14   15
[4,]   16   17   18   19   20
> x[c(2, 3), c(3, 4)] # 选取2,3行,和3,4列
     [,1] [,2]
[1,]    8    9
[2,]   13   14

或者是省略参数进行行列的索引:

> x[2,]
[1]  6  7  8  9 10
> x[,2]
[1]  2  7 12 17

还有我刚刚说的删除行列,然后还有一点就是,不同的参数是可以用到索引和删除的:

> x[-2, -2]
     [,1] [,2] [,3] [,4]
[1,]    1    3    4    5
[2,]   11   13   14   15
[3,]   16   18   19   20
> x[c(-1, -4), 3] # 删除第一行,第四行后,输出第三行的向量
[1]  8 13

我们假设我们给矩阵的行列取了名字,那咋弄?其实也是一样的,只是可以用名字找到ta而已:

> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    6    7    8    9   10
[3,]   11   12   13   14   15
[4,]   16   17   18   19   20
> dimnames(x) <- list(rname, cname)
> x
   C1 C2 C3 C4 C5
R1  1  2  3  4  5
R2  6  7  8  9 10
R3 11 12 13 14 15
R4 16 17 18 19 20
> x['R3', ]
C1 C2 C3 C4 C5 
11 12 13 14 15 
> x[, 'C4']
R1 R2 R3 R4 
 4  9 14 19 
> x['R3', 'C4']
[1] 14

3.2.4. 矩阵的运算

矩阵的运算,我想学过线性代数的同学应该都是会的,在这里简单的讲一下,矩阵的运算其实还是和前面向量的运算基本操作是一样的,什么叫一样的呢?就是指对应位置上进行操作,除了矩阵有一个特殊的乘法的性质:

> x <- matrix(1:20, 4, 5)
> y <- matrix(1:20, 5, 4)
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> 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
> x + 1 # 加法
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    6   10   14   18
[2,]    3    7   11   15   19
[3,]    4    8   12   16   20
[4,]    5    9   13   17   21
> x * 2 # 乘法
     [,1] [,2] [,3] [,4] [,5]
[1,]    2   10   18   26   34
[2,]    4   12   20   28   36
[3,]    6   14   22   30   38
[4,]    8   16   24   32   40
> x / 2 # 除法
     [,1] [,2] [,3] [,4] [,5]
[1,]  0.5  2.5  4.5  6.5  8.5
[2,]  1.0  3.0  5.0  7.0  9.0
[3,]  1.5  3.5  5.5  7.5  9.5
[4,]  2.0  4.0  6.0  8.0 10.0
> x ** 2 # 幂运算
     [,1] [,2] [,3] [,4] [,5]
[1,]    1   25   81  169  289
[2,]    4   36  100  196  324
[3,]    9   49  121  225  361
[4,]   16   64  144  256  400
> x + y # 不同样子的矩阵不能加
Error in x + y : non-conformable arrays
> x * y # 不同样子的矩阵不能内积
Error in x * y : non-conformable arrays
> x %*% y # 4*5和5*4的矩阵可以外积
     [,1] [,2] [,3] [,4]
[1,]  175  400  625  850
[2,]  190  440  690  940
[3,]  205  480  755 1030
[4,]  220  520  820 1120

一些用来简便计算的函数,实在是挺简单的,所以就直接列出来不细讲:

> x
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20
> sum(x) # 求和
[1] 210
> colSums(x) # 列和
[1] 10 26 42 58 74
> rowSums(x) # 行和
[1] 45 50 55 60
> colMeans(x) # 列平均值
[1]  2.5  6.5 10.5 14.5 18.5
> rowMeans(x) # 行平均值
[1]  9 10 11 12
> diag(x) # 返回对角线上的值
[1]  1  6 11 16
> t(x) # 矩阵转置
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12
[4,]   13   14   15   16
[5,]   17   18   19   20

3.3. 列表

R语言中的列表是一种很复杂但也很重要的数据结构,这里的列表不像其他语言中的列表一样,单纯表示为一个数组。

R的列表是一些对象的集合,里面可以有向量、矩阵、数据框,或者另一个列表。所以可以知道,列表是R中最大的容器,类似于向量的结构,是一个一维数据的集合。和向量不同的地方就是可以存储不同的数据结构,包括列表本身。

我们的数据集中,state.center(美国各个州的经纬度) 就是一个列表,我们看一下:

> state.center
$x
 [1]  -86.7509 -127.2500 -111.6250  -92.2992
 [5] -119.7730 -105.5130  -72.3573  -74.9841
 [9]  -81.6850  -83.3736 -126.2500 -113.9300
[13]  -89.3776  -86.0808  -93.3714  -98.1156
[17]  -84.7674  -92.2724  -68.9801  -76.6459
[21]  -71.5800  -84.6870  -94.6043  -89.8065
[25]  -92.5137 -109.3200  -99.5898 -116.8510
[29]  -71.3924  -74.2336 -105.9420  -75.1449
[33]  -78.4686 -100.0990  -82.5963  -97.1239
[37] -120.0680  -77.4500  -71.1244  -80.5056
[41]  -99.7238  -86.4560  -98.7857 -111.3300
[45]  -72.5450  -78.2005 -119.7460  -80.6665
[49]  -89.9941 -107.2560

$y
 [1] 32.5901 49.2500 34.2192 34.7336 36.5341 38.6777
 [7] 41.5928 38.6777 27.8744 32.3329 31.7500 43.5648
[13] 40.0495 40.0495 41.9358 38.4204 37.3915 30.6181
[19] 45.6226 39.2778 42.3645 43.1361 46.3943 32.6758
[25] 38.3347 46.8230 41.3356 39.1063 43.3934 39.9637
[31] 34.4764 43.1361 35.4195 47.2517 40.2210 35.5053
[37] 43.9078 40.9069 41.5928 33.6190 44.3365 35.6767
[43] 31.3897 39.1063 44.2508 37.5630 47.4231 38.4204
[49] 44.5937 43.0504

3.3.1. 创建列表

和往常一样,学习这个数据结构要先会创建ta:

> ls = list(1, "str", T, matrix(1:20, 4, 5)) # 创建列表
> ls
[[1]]
[1] 1

[[2]]
[1] "str"

[[3]]
[1] TRUE

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

其实列表这样就已经创建好了,很简单。当然,像其他数据结构一样,我们可以为每一项取名儿:

> ls = list(first=1, second="str", third=T, forth=matrix(1:20, 4, 5)) # 直接在参数前面给ta取名
> ls
$first
[1] 1

$second
[1] "str"

$third
[1] TRUE

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

3.3.2. 列表索引

列表的索引和向量的索引又双叒叕是非常像的,我把相同的地方在这里简单的敲一遍吧:

> ls
$first
[1] 1

$second
[1] "str"

$third
[1] TRUE

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls[1] # 索引单个值
$first
[1] 1

> ls[c(2, 4)] # 访问多个元素
$second
[1] "str"

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls[c('second', 'forth')] # 用名字访问
$second
[1] "str"

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls[-4] # 负索引删除 
$first
[1] 1

$second
[1] "str"

$third
[1] TRUE

既然说了相同,那必有不同的地方,就是使用$符号进行列表元素的索引,方法高效,也很方便:

> ls$third # 直接索引名字为third的元素
[1] TRUE

关于索引的方法也是有讲究的,我们先看一下下面这个案例:

> ls[4]
$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls[[4]]
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

你有发现有什么不同吗?从输出上来看是没有什么不同,只是ls[[4]]中少了一个$forth而已。但是这个地方是从根本上进行了改变。

  • $forth说明了什么?说明ls[4]其实是一个列表,我们可以发现ta和前面的列表构造很像,不过只有一个数罢了。所以我们可以看出来,ls[4]只是把第四项取出来成为了一个新的列表了(我们也能发现R语言所有的数据结构,在索引的时候都可以选择多个数据,因为这样方便构造一个新的一样的数据结构)。

  • 然后当我们输入ls[[4]]的时候,可以发现输出的就是一个矩阵,也就是我们把这个元素原本的属性输出来了!

  • 我们来验证一下:

    > class(ls[4])
    [1] "list"
    > class(ls[[4]])
    [1] "matrix" "array" 
    

    可见我们的猜测非常正确,哎嘿

讲这个有啥用呢?wok,用处可大了,我们赋值的时候总不能把一个matrix赋值给一个list吧!所以我们赋值的时候就要注意了:

> ls
$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls[1] <- matrix(1:16, 4, 4) # 给ls[1]赋值
Warning message:
In ls[1] <- matrix(1:16, 4, 4) :
  number of items to replace is not a multiple of replacement length
> ls
$forth
[1] 1

> ls[[1]] <- matrix(1:16, 4, 4) # 给ls[[1]]赋值
> ls
$forth
     [,1] [,2] [,3] [,4]
[1,]    1    5    9   13
[2,]    2    6   10   14
[3,]    3    7   11   15
[4,]    4    8   12   16

> class(ls$forth) # 看看$索引的元素性质
[1] "matrix" "array" 
> ls$forth <- matrix(1:20, 4, 5) # 也可以给$索引的元素赋值
> ls
$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

3.3.3. 列表操作

我主要就讲两个列表操作吧,一个是追加,一个是删除。

首先是追加,追加和我们之前在向量中运用的技巧一样,可以用向量追加东西:

> ls
$first
[1] 1

$second
[1] "str"

$third
[1] TRUE

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls <- c(ls, list(matrix(1:20, 4, 5))) # 追加一个4*5的矩阵
> ls
$first
[1] 1

$second
[1] "str"

$third
[1] TRUE

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

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

还有一个就是删除,删除除了负索引,还可以使用别的方法,因为有的时候我们也想使用名称索引:

> ls
$first
[1] 1

$second
[1] "str"

$third
[1] TRUE

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

> ls$second <- NULL # 删除名称为second的元素
> ls
$first
[1] 1

$third
[1] TRUE

$forth
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

3.4. 数据框

作用:数据框用于模拟数据集,和SPSS或SAS中的数据集的概念是一致的。

简单der介绍:数据集通常是数据构成的矩形数组。统计学中将行称为观测,列称为变量,数据库中称为记录和字段,机器学习上称为示例与属性(根据不同的作用进行区分)。

(ps:数据框是一个矩形的结构,但不是由矩阵进行实现的,本质上是一个列表)。

3.4.1. 数据框的组成

数据框是由:列表+等长的向量,组成的。然后数据框的列表中的元素是必须有名字的!

我在这用Excel进行一个介绍:

所以在这里是很好理解的,我们的数据框就是被分成了这样的几个部分。

所以我们可以总结出几个数据框的特点:

  • 形状像矩阵,但是不是矩阵,因为矩阵必须为同一个数据类型
  • 数据框是一个规则的列表
  • 所以数据框的每一列类型相同,行的每一项数据类型的可以不同

然后我们的内置数据集中就有大量的数据框的结构:

> class(iris) # 鸢尾花数据集 
[1] "data.frame"
> class(mtcars) # 32辆车在11个指标上的数据
[1] "data.frame"

3.4.2. 数据框的构建

讲完概念,终于也到了构建数据框的时候了,构建数据框也不难,也是依靠一个函数:data.frame()来构建的。我们在data.frame()中放入一至多个,向量和矩阵,只要行数一样就可以合并了。

我们先来个简单的例子:

> data.frame(matrix(1:20, 4, 5))
  X1 X2 X3 X4 X5
1  1  5  9 13 17
2  2  6 10 14 18
3  3  7 11 15 19
4  4  8 12 16 20

从这个例子中我们发现了什么!发现了数据框的列是一定要有名字的!因为我们没有给他赋予名字,所以R自动为我们的矩阵创造了一个列名。

我们在来做一个合并的:

> df <- data.frame(matrix(1:20, 4, 5), c(21:24)) # 合并一个矩阵和一个向量
> df
  X1 X2 X3 X4 X5 c.21.24.
1  1  5  9 13 17       21
2  2  6 10 14 18       22
3  3  7 11 15 19       23
4  4  8 12 16 20       24

以上都是我们没有取名的例子,所以列名都是系统自动给的。下面我们用系统给的数据集来做一个案例。

我们知道state.name, state.abb, state.region, state.x77是美国50个州的各种数据,这四个分别为向量、向量、向量、矩阵,而且行名都对应为相应的州的名字:

> state.name # 州的名字
 [1] "Alabama"        "Alaska"         "Arizona"       
 [4] "Arkansas"       "California"     "Colorado"      
 [7] "Connecticut"    "Delaware"       "Florida"       
[10] "Georgia"        "Hawaii"         "Idaho"         
[13] "Illinois"       "Indiana"        "Iowa"          
[16] "Kansas"         "Kentucky"       "Louisiana"     
[19] "Maine"          "Maryland"       "Massachusetts" 
[22] "Michigan"       "Minnesota"      "Mississippi"   
[25] "Missouri"       "Montana"        "Nebraska"      
[28] "Nevada"         "New Hampshire"  "New Jersey"    
[31] "New Mexico"     "New York"       "North Carolina"
[34] "North Dakota"   "Ohio"           "Oklahoma"      
[37] "Oregon"         "Pennsylvania"   "Rhode Island"  
[40] "South Carolina" "South Dakota"   "Tennessee"     
[43] "Texas"          "Utah"           "Vermont"       
[46] "Virginia"       "Washington"     "West Virginia" 
[49] "Wisconsin"      "Wyoming"        
> state.abb # 名字的缩写
 [1] "AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL"
[10] "GA" "HI" "ID" "IL" "IN" "IA" "KS" "KY" "LA"
[19] "ME" "MD" "MA" "MI" "MN" "MS" "MO" "MT" "NE"
[28] "NV" "NH" "NJ" "NM" "NY" "NC" "ND" "OH" "OK"
[37] "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT" "VT"
[46] "VA" "WA" "WV" "WI" "WY"
> state.region # 所在的地区
 [1] South         West          West         
 [4] South         West          West         
 [7] Northeast     South         South        
[10] South         West          West         
[13] North Central North Central North Central
[16] North Central South         South        
[19] Northeast     South         Northeast    
[22] North Central North Central South        
[25] North Central West          North Central
[28] West          Northeast     Northeast    
[31] West          Northeast     South        
[34] North Central North Central South        
[37] West          Northeast     Northeast    
[40] South         North Central South        
[43] South         West          Northeast    
[46] South         West          South        
[49] North Central West         
Levels: Northeast South North Central West
> state.x77 # 50个州的详细数据
               Population Income Illiteracy
Alabama              3615   3624        2.1
Alaska                365   6315        1.5
Arizona              2212   4530        1.8
Arkansas             2110   3378        1.9
California          21198   5114        1.1
Colorado             2541   4884        0.7
Connecticut          3100   5348        1.1
Delaware              579   4809        0.9
Florida              8277   4815        1.3
Georgia              4931   4091        2.0
Hawaii                868   4963        1.9
Idaho                 813   4119        0.6
Illinois            11197   5107        0.9
Indiana              5313   4458        0.7
Iowa                 2861   4628        0.5
Kansas               2280   4669        0.6
Kentucky             3387   3712        1.6
Louisiana            3806   3545        2.8
Maine                1058   3694        0.7
Maryland             4122   5299        0.9
Massachusetts        5814   4755        1.1
Michigan             9111   4751        0.9
Minnesota            3921   4675        0.6
Mississippi          2341   3098        2.4
Missouri             4767   4254        0.8
Montana               746   4347        0.6
Nebraska             1544   4508        0.6
Nevada                590   5149        0.5
New Hampshire         812   4281        0.7
New Jersey           7333   5237        1.1
New Mexico           1144   3601        2.2
New York            18076   4903        1.4
North Carolina       5441   3875        1.8
North Dakota          637   5087        0.8
Ohio                10735   4561        0.8
Oklahoma             2715   3983        1.1
Oregon               2284   4660        0.6
Pennsylvania        11860   4449        1.0
Rhode Island          931   4558        1.3
South Carolina       2816   3635        2.3
South Dakota          681   4167        0.5
Tennessee            4173   3821        1.7
Texas               12237   4188        2.2
Utah                 1203   4022        0.6
Vermont               472   3907        0.6
Virginia             4981   4701        1.4
Washington           3559   4864        0.6
West Virginia        1799   3617        1.4
Wisconsin            4589   4468        0.7
Wyoming               376   4566        0.6
               Life Exp Murder HS Grad Frost   Area
Alabama           69.05   15.1    41.3    20  50708
Alaska            69.31   11.3    66.7   152 566432
Arizona           70.55    7.8    58.1    15 113417
Arkansas          70.66   10.1    39.9    65  51945
California        71.71   10.3    62.6    20 156361
Colorado          72.06    6.8    63.9   166 103766
Connecticut       72.48    3.1    56.0   139   4862
Delaware          70.06    6.2    54.6   103   1982
Florida           70.66   10.7    52.6    11  54090
Georgia           68.54   13.9    40.6    60  58073
Hawaii            73.60    6.2    61.9     0   6425
Idaho             71.87    5.3    59.5   126  82677
Illinois          70.14   10.3    52.6   127  55748
Indiana           70.88    7.1    52.9   122  36097
Iowa              72.56    2.3    59.0   140  55941
Kansas            72.58    4.5    59.9   114  81787
Kentucky          70.10   10.6    38.5    95  39650
Louisiana         68.76   13.2    42.2    12  44930
Maine             70.39    2.7    54.7   161  30920
Maryland          70.22    8.5    52.3   101   9891
Massachusetts     71.83    3.3    58.5   103   7826
Michigan          70.63   11.1    52.8   125  56817
Minnesota         72.96    2.3    57.6   160  79289
Mississippi       68.09   12.5    41.0    50  47296
Missouri          70.69    9.3    48.8   108  68995
Montana           70.56    5.0    59.2   155 145587
Nebraska          72.60    2.9    59.3   139  76483
Nevada            69.03   11.5    65.2   188 109889
New Hampshire     71.23    3.3    57.6   174   9027
New Jersey        70.93    5.2    52.5   115   7521
New Mexico        70.32    9.7    55.2   120 121412
New York          70.55   10.9    52.7    82  47831
North Carolina    69.21   11.1    38.5    80  48798
North Dakota      72.78    1.4    50.3   186  69273
Ohio              70.82    7.4    53.2   124  40975
Oklahoma          71.42    6.4    51.6    82  68782
Oregon            72.13    4.2    60.0    44  96184
Pennsylvania      70.43    6.1    50.2   126  44966
Rhode Island      71.90    2.4    46.4   127   1049
South Carolina    67.96   11.6    37.8    65  30225
South Dakota      72.08    1.7    53.3   172  75955
Tennessee         70.11   11.0    41.8    70  41328
Texas             70.90   12.2    47.4    35 262134
Utah              72.90    4.5    67.3   137  82096
Vermont           71.64    5.5    57.1   168   9267
Virginia          70.08    9.5    47.8    85  39780
Washington        71.72    4.3    63.5    32  66570
West Virginia     69.48    6.7    41.6   100  24070
Wisconsin         72.48    3.0    54.5   149  54464
Wyoming           70.29    6.9    62.9   173  97203

那我们这里的三个向量和一个矩阵就可以合并称为一个描述美国的很好的数据框,我们来试一试:

> df <- data.frame(state.name, state.abb, state.region, state.x77) # 将这四个属性进行合并

然后这就是呈现在我们面前的构成的数据框:

而且打开一看,属实觉得界面比Excel界面好看,学R学出了幻觉

3.4.3. 数据框的索引

构建一个数据框还是一个小事,最重要的还是我们怎么去使用我们的数据框,第一个要做的自然就是索引。

首先讲一个又双叒叕和其他数据结构,可以直接索引列的值

> df[c(2, 4)] # 查询2,4列
               state.abb Population
Alabama               AL       3615
Alaska                AK        365
Arizona               AZ       2212
Arkansas              AR       2110
California            CA      21198
Colorado              CO       2541
Connecticut           CT       3100
Delaware              DE        579
Florida               FL       8277
Georgia               GA       4931
Hawaii                HI        868
Idaho                 ID        813
Illinois              IL      11197
Indiana               IN       5313
Iowa                  IA       2861
Kansas                KS       2280
Kentucky              KY       3387
Louisiana             LA       3806
Maine                 ME       1058
Maryland              MD       4122
Massachusetts         MA       5814
Michigan              MI       9111
Minnesota             MN       3921
Mississippi           MS       2341
Missouri              MO       4767
Montana               MT        746
Nebraska              NE       1544
Nevada                NV        590
New Hampshire         NH        812
New Jersey            NJ       7333
New Mexico            NM       1144
New York              NY      18076
North Carolina        NC       5441
North Dakota          ND        637
Ohio                  OH      10735
Oklahoma              OK       2715
Oregon                OR       2284
Pennsylvania          PA      11860
Rhode Island          RI        931
South Carolina        SC       2816
South Dakota          SD        681
Tennessee             TN       4173
Texas                 TX      12237
Utah                  UT       1203
Vermont               VT        472
Virginia              VA       4981
Washington            WA       3559
West Virginia         WV       1799
Wisconsin             WI       4589
Wyoming               WY        376
> df[-c(3:9)] # 删除3:9列
                   state.name state.abb Frost   Area
Alabama               Alabama        AL    20  50708
Alaska                 Alaska        AK   152 566432
Arizona               Arizona        AZ    15 113417
Arkansas             Arkansas        AR    65  51945
California         California        CA    20 156361
Colorado             Colorado        CO   166 103766
Connecticut       Connecticut        CT   139   4862
Delaware             Delaware        DE   103   1982
Florida               Florida        FL    11  54090
Georgia               Georgia        GA    60  58073
Hawaii                 Hawaii        HI     0   6425
Idaho                   Idaho        ID   126  82677
Illinois             Illinois        IL   127  55748
Indiana               Indiana        IN   122  36097
Iowa                     Iowa        IA   140  55941
Kansas                 Kansas        KS   114  81787
Kentucky             Kentucky        KY    95  39650
Louisiana           Louisiana        LA    12  44930
Maine                   Maine        ME   161  30920
Maryland             Maryland        MD   101   9891
Massachusetts   Massachusetts        MA   103   7826
Michigan             Michigan        MI   125  56817
Minnesota           Minnesota        MN   160  79289
Mississippi       Mississippi        MS    50  47296
Missouri             Missouri        MO   108  68995
Montana               Montana        MT   155 145587
Nebraska             Nebraska        NE   139  76483
Nevada                 Nevada        NV   188 109889
New Hampshire   New Hampshire        NH   174   9027
New Jersey         New Jersey        NJ   115   7521
New Mexico         New Mexico        NM   120 121412
New York             New York        NY    82  47831
North Carolina North Carolina        NC    80  48798
North Dakota     North Dakota        ND   186  69273
Ohio                     Ohio        OH   124  40975
Oklahoma             Oklahoma        OK    82  68782
Oregon                 Oregon        OR    44  96184
Pennsylvania     Pennsylvania        PA   126  44966
Rhode Island     Rhode Island        RI   127   1049
South Carolina South Carolina        SC    65  30225
South Dakota     South Dakota        SD   172  75955
Tennessee           Tennessee        TN    70  41328
Texas                   Texas        TX    35 262134
Utah                     Utah        UT   137  82096
Vermont               Vermont        VT   168   9267
Virginia             Virginia        VA    85  39780
Washington         Washington        WA    32  66570
West Virginia   West Virginia        WV   100  24070
Wisconsin           Wisconsin        WI   149  54464
Wyoming               Wyoming        WY   173  97203

上面这个选择索引和删除索引返回的都是数据框对象,和我们之前学列表的时候是一样的,可以类比。那怎么把数据框变成原数据类型的实体呢?其实和以前也是一样的~

> df[[2]] # 用双中括号进行取值
 [1] "AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL" "GA" "HI"
[12] "ID" "IL" "IN" "IA" "KS" "KY" "LA" "ME" "MD" "MA" "MI"
[23] "MN" "MS" "MO" "MT" "NE" "NV" "NH" "NJ" "NM" "NY" "NC"
[34] "ND" "OH" "OK" "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT"
[45] "VT" "VA" "WA" "WV" "WI" "WY"
> df$state.abb # 用$符号进行取值
 [1] "AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL" "GA" "HI"
[12] "ID" "IL" "IN" "IA" "KS" "KY" "LA" "ME" "MD" "MA" "MI"
[23] "MN" "MS" "MO" "MT" "NE" "NV" "NH" "NJ" "NM" "NY" "NC"
[34] "ND" "OH" "OK" "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT"
[45] "VT" "VA" "WA" "WV" "WI" "WY"

我们现在已经知道怎么取列的值了,然后我们自然就会想怎么去取某个位置的值,或者怎么取某一行的值。这就要牵扯到两个参数的索引方法的应用了:

> df <- array(1:16, c(4, 4), dimnames = list(c('R1', 'R2', 'R3', 'R4'), c('C1', 'C2', 'C3', 'C4')))
> df <- data.frame(df)
> df
   C1 C2 C3 C4
R1  1  5  9 13
R2  2  6 10 14
R3  3  7 11 15
R4  4  8 12 16
> df['R3', 'C4'] # 输出第三行第四列的值
[1] 15

所以我们很清楚的就能知道,两个参数就是先行后列,所以我们想输出某一行或某一列也就可以使用这样的方法:

> df['R3', ]
   C1 C2 C3 C4
R3  3  7 11 15
> df[, 'C4']
[1] 13 14 15 16

然后R还给我们提供两种面向数据框比较方便的函数:attach函数和with函数。

  • attach函数:其实就是将数据框加载入系统,然后列名就相当于称为了变量,可以直接调用了(然后我们可以用detach函数关闭加载),我们来试试:

    > attach(df)
    > C1
    [1] 1 2 3 4
    > C2
    [1] 5 6 7 8
    > detach(df)
    > C1
    Error: object 'C1' not found
    > C2
    Error: object 'C2' not found
    
  • with函数:这个函数的作用就类似于$符号的作用,可以索引某一个数据框的某一列,还能进行一些操作,虽然大部分时间没有$符号好用:

    > with(df, {C1}) # 输出df数据框的C1列
    [1] 1 2 3 4
    > with(df, {sum(C1)}) # 输出df数据框C1列的和
    [1] 10
    

3.5. 因子

因子也是R中非常重要的一个数据结构,要了解因子是什么,我们要先了解一下变量有哪些种类:

  • 名义型变量:每个值具有独立性,如每个城市的名字;
  • 有序型变量:在上下两者之间,有连续的变化,不是数值,比如考试评级,ABCDE这样的。
  • 连续型变量:在一个范围内变动的数字型变量,如考试分数。

在R中,名义型变量和有序型变量就被称为因子,这些变量都以等级分类,比如:优、良、差,被称为等级。由这些等级构成的向量就被称为因子。

因子最大的作用就是用来分类,计算频数和频率。

3.5.1. 因子的作用

上面所说,因子可以用于分类,将变量以等级来区分。所以因子在应用上可以有:

  • 计算频数
  • 独立性检验
  • 相关性检验
  • 方差分析
  • 因子分析

我们以mtcars数据集做计算频数的举例:

> mtcars
                     mpg cyl  disp  hp drat    wt
Mazda RX4           21.0   6 160.0 110 3.90 2.620
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875
Datsun 710          22.8   4 108.0  93 3.85 2.320
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440
Valiant             18.1   6 225.0 105 2.76 3.460
Duster 360          14.3   8 360.0 245 3.21 3.570
Merc 240D           24.4   4 146.7  62 3.69 3.190
Merc 230            22.8   4 140.8  95 3.92 3.150
Merc 280            19.2   6 167.6 123 3.92 3.440
Merc 280C           17.8   6 167.6 123 3.92 3.440
Merc 450SE          16.4   8 275.8 180 3.07 4.070
Merc 450SL          17.3   8 275.8 180 3.07 3.730
Merc 450SLC         15.2   8 275.8 180 3.07 3.780
Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250
Lincoln Continental 10.4   8 460.0 215 3.00 5.424
Chrysler Imperial   14.7   8 440.0 230 3.23 5.345
Fiat 128            32.4   4  78.7  66 4.08 2.200
Honda Civic         30.4   4  75.7  52 4.93 1.615
Toyota Corolla      33.9   4  71.1  65 4.22 1.835
Toyota Corona       21.5   4 120.1  97 3.70 2.465
Dodge Challenger    15.5   8 318.0 150 2.76 3.520
AMC Javelin         15.2   8 304.0 150 3.15 3.435
Camaro Z28          13.3   8 350.0 245 3.73 3.840
Pontiac Firebird    19.2   8 400.0 175 3.08 3.845
Fiat X1-9           27.3   4  79.0  66 4.08 1.935
Porsche 914-2       26.0   4 120.3  91 4.43 2.140
Lotus Europa        30.4   4  95.1 113 3.77 1.513
Ford Pantera L      15.8   8 351.0 264 4.22 3.170
Ferrari Dino        19.7   6 145.0 175 3.62 2.770
Maserati Bora       15.0   8 301.0 335 3.54 3.570
Volvo 142E          21.4   4 121.0 109 4.11 2.780
                     qsec vs am gear carb
Mazda RX4           16.46  0  1    4    4
Mazda RX4 Wag       17.02  0  1    4    4
Datsun 710          18.61  1  1    4    1
Hornet 4 Drive      19.44  1  0    3    1
Hornet Sportabout   17.02  0  0    3    2
Valiant             20.22  1  0    3    1
Duster 360          15.84  0  0    3    4
Merc 240D           20.00  1  0    4    2
Merc 230            22.90  1  0    4    2
Merc 280            18.30  1  0    4    4
Merc 280C           18.90  1  0    4    4
Merc 450SE          17.40  0  0    3    3
Merc 450SL          17.60  0  0    3    3
Merc 450SLC         18.00  0  0    3    3
Cadillac Fleetwood  17.98  0  0    3    4
Lincoln Continental 17.82  0  0    3    4
Chrysler Imperial   17.42  0  0    3    4
Fiat 128            19.47  1  1    4    1
Honda Civic         18.52  1  1    4    2
Toyota Corolla      19.90  1  1    4    1
Toyota Corona       20.01  1  0    3    1
Dodge Challenger    16.87  0  0    3    2
AMC Javelin         17.30  0  0    3    2
Camaro Z28          15.41  0  0    3    4
Pontiac Firebird    17.05  0  0    3    2
Fiat X1-9           18.90  1  1    4    1
Porsche 914-2       16.70  0  1    5    2
Lotus Europa        16.90  1  1    5    2
Ford Pantera L      14.50  0  1    5    4
Ferrari Dino        15.50  0  1    5    6
Maserati Bora       14.60  0  1    5    8
Volvo 142E          18.60  1  1    4    2

根据cyl汽车缸数,我们可以计算这些汽车的频数:

> table(mtcars$cyl) # table函数用于频数统计

 4  6  8 
11  7 14 

备注:可以用来做因子的均可以这样做。

3.5.2. 因子的定义

我们这里叫因子的定义,而不叫因子的构造,本质上是因为因子是基于向量发展而来的,向量可以转变为因子。

我们可以使用factor函数定义一个可以作为因子的向量,在这里我们举例:

> f <- factor(c('red', 'green', 'blue', 'green', 'blue'))
> f
[1] red   green blue  green blue 
Levels: blue green red
> class(f)
[1] "factor"

显而易见,我们所有的‘等级’,在这里也就是三种颜色,被认为做等级,构造成了一个因子。

除了让系统自行构造因子的等级,我们还可以自己定义等级:

> f <- factor(c('a', 'b', 'c'), ordered = T, levels = c('a', 'b', 'c'))
> f
[1] a b c
Levels: a < b < c

第一个参数好理解,是我们的向量,levels参数好理解,是我们设定的等级。那我们还有一个参数ordered是什么呢?其实ordered是判断是否要根据输入的等级进行排序。我们可以看到输出的等级是有分大小的,所以ordered判定为TRUE是让我们输入的因子从小到大进行排序

factor除了定义一个新的因子,还可以将一个向量定义为因子。还是用之前的例子,mtcars中的汽车缸数cyl就可以转化为因子。

> f <- factor(mtcars$cyl)
> f
 [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8
[26] 4 4 4 8 6 8 4
Levels: 4 6 8

因子还有什么特性呢?既然我们说因子可以用来分组,那我们尝试一下在画图上有没有什么不一样的。一般我们都知道一堆数据在画图的时候都会变成一堆点,那分了组是不是就是柱状图了呢?我们来试试:

> plot(mtcars$cyl)
> plot(factor(mtcars$cyl))

下面的图就是运行的结果:

所以我们的想法是对的,其实从table的分组结果也能猜到这个效果。

除此之外,我们还会将连续区间划成段进行分组,比如考试分数满分为100分,每十分我们可以划一段,这里我们就可以用到cut函数了:

> plot(mtcars$cyl)
> plot(factor(mtcars$cyl))
> ls <- c(1, 65, 23, 40, 80, 99, 29, 100, 34)
> cut(ls, c(seq(0, 100, 10)))
[1] (0,10]   (60,70]  (20,30]  (30,40]  (70,80] 
[6] (90,100] (20,30]  (90,100] (30,40] 
10 Levels: (0,10] (10,20] (20,30] (30,40] ... (90,100]

这样我们列表中的每个数都被这个等级取代使用了。

然后我们看完知识点后,也可以观察一下系统的数据集中,state.division和stata.region是因子类型的数据。

3.6. 时间序列

R中有很多内置的时间序列数据集,我们可以列举几个:

> sunspots # 太阳黑子数
       Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep
1749  58.0  62.6  70.0  55.7  85.0  83.5  94.8  66.3  75.9
1750  73.3  75.9  89.2  88.3  90.0 100.0  85.4 103.0  91.2
1751  70.0  43.5  45.3  56.4  60.7  50.7  66.3  59.8  23.5
1752  35.0  50.0  71.0  59.3  59.7  39.6  78.4  29.3  27.1
1753  44.0  32.0  45.7  38.0  36.0  31.7  22.2  39.0  28.0
1754   0.0   3.0   1.7  13.7  20.7  26.7  18.8  12.3   8.2
1755  10.2  11.2   6.8   6.5   0.0   0.0   8.6   3.2  17.8
1756  12.5   7.1   5.4   9.4  12.5  12.9   3.6   6.4  11.8
1757  14.1  21.2  26.2  30.0  38.1  12.8  25.0  51.3  39.7
1758  37.6  52.0  49.0  72.3  46.4  45.0  44.0  38.7  62.5
1759  48.3  44.0  46.8  47.0  49.0  50.0  51.0  71.3  77.2
1760  67.3  59.5  74.7  58.3  72.0  48.3  66.0  75.6  61.3
1761  70.0  91.0  80.7  71.7 107.2  99.3  94.1  91.1 100.7
1762  43.8  72.8  45.7  60.2  39.9  77.1  33.8  67.7  68.5
1763  56.5  31.9  34.2  32.9  32.7  35.8  54.2  26.5  68.1
1764  59.7  59.7  40.2  34.4  44.3  30.0  30.0  30.0  28.2
1765  24.0  26.0  25.0  22.0  20.2  20.0  27.0  29.7  16.0
1766  12.0  11.0  36.6   6.0  26.8   3.0   3.3   4.0   4.3
1767  27.4  30.0  43.0  32.9  29.8  33.3  21.9  40.8  42.7
1768  53.5  66.1  46.3  42.7  77.7  77.4  52.6  66.8  74.8
1769  73.9  64.2  64.3  96.7  73.6  94.4 118.6 120.3 148.8
1770 104.0 142.5  80.1  51.0  70.1  83.3 109.8 126.3 104.4
1771  36.0  46.2  46.7  64.9 152.7 119.5  67.7  58.5 101.4
1772 100.9  90.8  31.1  92.2  38.0  57.0  77.3  56.2  50.5
1773  54.6  29.0  51.2  32.9  41.1  28.4  27.7  12.7  29.3
1774  46.8  65.4  55.7  43.8  51.3  28.5  17.5   6.6   7.9
1775   4.4   0.0  11.6  11.2   3.9  12.3   1.0   7.9   3.2
1776  21.7  11.6   6.3  21.8  11.2  19.0   1.0  24.2  16.0
1777  45.0  36.5  39.0  95.5  80.3  80.7  95.0 112.0 116.2
1778 177.3 109.3 134.0 145.0 238.9 171.6 153.0 140.0 171.7
1779 114.7 165.7 118.0 145.0 140.0 113.7 143.0 112.0 111.0
1780  70.0  98.0  98.0  95.0 107.2  88.0  86.0  86.0  93.7
1781  98.7  74.7  53.0  68.3 104.7  97.7  73.5  66.0  51.0
1782  54.0  37.5  37.0  41.0  54.3  38.0  37.0  44.0  34.0
1783  28.0  38.7  26.7  28.3  23.0  25.2  32.2  20.0  18.0
1784  13.0   8.0  11.0  10.0   6.0   9.0   6.0  10.0  10.0
1785   6.5   8.0   9.0  15.7  20.7  26.3  36.3  20.0  32.0
1786  37.2  47.6  47.7  85.4  92.3  59.0  83.0  89.7 111.5
1787 134.7 106.0  87.4 127.2 134.8  99.2 128.0 137.2 157.3
1788 138.0 129.2 143.3 108.5 113.0 154.2 141.5 136.0 141.0
1789 114.0 125.3 120.0 123.3 123.5 120.0 117.0 103.0 112.0
1790 103.0 127.5  96.3  94.0  93.0  91.0  69.3  87.0  77.3
1791  72.7  62.0  74.0  77.2  73.7  64.2  71.0  43.0  66.5
1792  58.0  64.0  63.0  75.7  62.0  61.0  45.8  60.0  59.0
1793  56.0  55.0  55.5  53.0  52.3  51.0  50.0  29.3  24.0
1794  45.0  44.0  38.0  28.4  55.7  41.5  41.0  40.0  11.1
1795  21.4  39.9  12.6  18.6  31.0  17.1  12.9  25.7  13.5
1796  22.0  23.8  15.7  31.7  21.0   6.7  26.9   1.5  18.4
1797  14.4   4.2   4.0   4.0   7.3  11.1   4.3   6.0   5.7
1798   2.0   4.0  12.4   1.1   0.0   0.0   0.0   3.0   2.4
1799   1.6  12.6  21.7   8.4   8.2  10.6   2.1   0.0   0.0
1800   6.9   9.3  13.9   0.0   5.0  23.7  21.0  19.5  11.5
1801  27.0  29.0  30.0  31.0  32.0  31.2  35.0  38.7  33.5
1802  47.8  47.0  40.8  42.0  44.0  46.0  48.0  50.0  51.8
1803  50.0  50.8  29.5  25.0  44.3  36.0  48.3  34.1  45.3
1804  45.3  48.3  48.0  50.6  33.4  34.8  29.8  43.1  53.0
1805  61.0  44.1  51.4  37.5  39.0  40.5  37.6  42.7  44.4
1806  39.0  29.6  32.7  27.7  26.4  25.6  30.0  26.3  24.0
1807  12.0  12.2   9.6  23.8  10.0  12.0  12.7  12.0   5.7
1808   0.0   4.5   0.0  12.3  13.5  13.5   6.7   8.0  11.7
1809   7.2   9.2   0.9   2.5   2.0   7.7   0.3   0.2   0.4
1810   0.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0
1811   0.0   0.0   0.0   0.0   0.0   0.0   6.6   0.0   2.4
1812  11.3   1.9   0.7   0.0   1.0   1.3   0.5  15.6   5.2
1813   0.0  10.3   1.9  16.6   5.5  11.2  18.3   8.4  15.3
1814  22.2  12.0   5.7  23.8   5.8  14.9  18.5   2.3   8.1
1815  19.2  32.2  26.2  31.6   9.8  55.9  35.5  47.2  31.5
1816  26.3  68.8  73.7  58.8  44.3  43.6  38.8  23.2  47.8
1817  36.4  57.9  96.2  26.4  21.2  40.0  50.0  45.0  36.7
1818  34.9  22.4  25.4  34.5  53.1  36.4  28.0  31.5  26.1
1819  32.5  20.7   3.7  20.2  19.6  35.0  31.4  26.1  14.9
1820  19.2  26.6   4.5  19.4  29.3  10.8  20.6  25.9   5.2
1821  21.5   4.3   5.7   9.2   1.7   1.8   2.5   4.8   4.4
1822   0.0   0.9  16.1  13.5   1.5   5.6   7.9   2.1   0.0
1823   0.0   0.0   0.6   0.0   0.0   0.0   0.5   0.0   0.0
1824  21.6  10.8   0.0  19.4   2.8   0.0   0.0   1.4  20.5
1825   5.0  15.5  22.4   3.8  15.4  15.4  30.9  25.4  15.7
1826  17.7  18.2  36.7  24.0  32.4  37.1  52.5  39.6  18.9
1827  34.6  47.4  57.8  46.0  56.3  56.7  42.9  53.7  49.6
1828  52.8  64.4  65.0  61.1  89.1  98.0  54.3  76.4  50.4
1829  43.0  49.4  72.3  95.0  67.5  73.9  90.8  78.3  52.8
1830  52.2  72.1  84.6 107.1  66.3  65.1  43.9  50.7  62.1
1831  47.5  50.1  93.4  54.6  38.1  33.4  45.2  54.9  37.9
       Oct   Nov   Dec
1749  75.5 158.6  85.2
1750  65.7  63.3  75.4
1751  23.2  28.5  44.0
1752  46.6  37.6  40.0
1753  25.0  20.0   6.7
1754  24.1  13.2   4.2
1755  23.7   6.8  20.0
1756  14.3  17.0   9.4
1757  32.5  64.7  33.5
1758  37.7  43.0  43.0
1759  59.7  46.3  57.0
1760  50.6  59.7  61.0
1761  88.7  89.7  46.0
1762  69.3  77.8  77.2
1763  46.3  60.9  61.4
1764  28.0  26.0  25.7
1765  14.0  14.0  13.0
1766   5.0   5.7  19.2
1767  44.1  54.7  53.3
1768  77.8  90.6 111.8
1769 158.2 148.1 112.0
1770 103.6 132.2 102.3
1771  90.0  99.7  95.7
1772  78.6  61.3  64.0
1773  26.3  40.9  43.2
1774  14.0  17.7  12.2
1775   5.6  15.1   7.9
1776  30.0  35.0  40.0
1777 106.5 146.0 157.3
1778 156.3 150.3 105.0
1779 124.0 114.0 110.0
1780  77.0  60.0  58.7
1781  27.3  67.0  35.2
1782  23.2  31.5  30.0
1783   8.0  15.0  10.5
1784   8.0  17.0  14.0
1785  47.2  40.2  27.3
1786 112.3 116.0 112.7
1787 157.0 141.5 174.0
1788 142.0  94.7 129.5
1789  89.7 134.0 135.5
1790  84.3  82.0  74.0
1791  61.7  67.0  66.0
1792  59.0  57.0  56.0
1793  47.0  44.0  45.7
1794  28.5  67.4  51.4
1795  19.5  25.0  18.0
1796  11.0   8.4   5.1
1797   6.9   5.8   3.0
1798   1.5  12.5   9.9
1799   4.6   2.7   8.6
1800  12.3  10.5  40.1
1801  32.6  39.8  48.2
1802  38.5  34.5  50.0
1803  54.3  51.0  48.0
1804  62.3  61.0  60.0
1805  29.4  41.0  38.3
1806  27.0  25.0  24.0
1807   8.0   2.6   0.0
1808   4.7  10.5  12.3
1809   0.0   0.0   0.0
1810   0.0   0.0   0.0
1811   6.1   0.8   1.1
1812   3.9   7.9  10.1
1813  27.8  16.7  14.3
1814  19.3  14.5  20.1
1815  33.5  37.2  65.0
1816  56.4  38.1  29.9
1817  25.6  28.9  28.4
1818  31.7  10.9  25.8
1819  27.5  25.1  30.6
1820   9.0   7.9   9.7
1821  18.8   4.4   0.0
1822   0.4   0.0   0.0
1823   0.0   0.0  20.4
1824  25.2   0.0   0.8
1825  15.6  11.7  22.0
1826  50.6  39.5  68.1
1827  57.2  48.2  46.1
1828  54.7  57.0  46.6
1829  57.2  67.6  56.5
1830  84.4  81.2  82.1
1831  46.2  43.5  28.9
 [ reached getOption("max.print") -- omitted 152 rows ]
> presidents # 美国总统支持率
     Qtr1 Qtr2 Qtr3 Qtr4
1945   NA   87   82   75
1946   63   50   43   32
1947   35   60   54   55
1948   36   39   NA   NA
1949   69   57   57   51
1950   45   37   46   39
1951   36   24   32   23
1952   25   32   NA   32
1953   59   74   75   60
1954   71   61   71   57
1955   71   68   79   73
1956   76   71   67   75
1957   79   62   63   57
1958   60   49   48   52
1959   57   62   61   66
1960   71   62   61   57
1961   72   83   71   78
1962   79   71   62   74
1963   76   64   62   57
1964   80   73   69   69
1965   71   64   69   62
1966   63   46   56   44
1967   44   52   38   46
1968   36   49   35   44
1969   59   65   65   56
1970   66   53   61   52
1971   51   48   54   49
1972   49   61   NA   NA
1973   68   44   40   27
1974   28   25   24   24

看了这两个时间序列数据集,我们来看一下ta的性质:

> class(sunspots)
[1] "ts"
> class(presidents)
[1] "ts"
> presidents$Qtr1 # 可见时间序列不能索引列
Error in presidents$Qtr1 : $ operator is invalid for atomic vectors

我们上面讲的时间序列都和数据框很像,然后我们看一种标准的时间序列格式:

> airmiles
Time Series:
Start = 1937 
End = 1960 
Frequency = 1 
 [1]   412   480   683  1052  1385  1418  1634  2178  3362
[10]  5948  6109  5981  6753  8003 10566 12528 14760 16769
[19] 19819 22362 25340 25343 29269 30514

其中表示了从start到end中在frequency频率中的每个点的数据。

3.6.1. 日期和时间类

日期和时间专门有一个类date:

> Sys.Date() # 获取当前系统时间
[1] "2021-08-03"
> class(Sys.Date())
[1] "Date"
> time <- '2021-08-03'
> class(time)
[1] "character"
> as.Date(time) # 转化为日期类
[1] "2021-08-03"
> class(as.Date(time))
[1] "Date"
> as.Date('08-03-2021', format = '%m-%d-%Y') # format参数用于确定日期的格式
[1] "2021-08-03"
> as.Date('08,03,2021', format = '%m,%d,%Y')
[1] "2021-08-03"

date类也和普通的数据类一样,可以用一些用在数值上的函数:

> seq(as.Date('2001-01-01'), as.Date('2008-08-08'), by = 111) # 用于在区间内取值,因为是日期类,自然用日期表示
 [1] "2001-01-01" "2001-04-22" "2001-08-11" "2001-11-30"
 [5] "2002-03-21" "2002-07-10" "2002-10-29" "2003-02-17"
 [9] "2003-06-08" "2003-09-27" "2004-01-16" "2004-05-06"
[13] "2004-08-25" "2004-12-14" "2005-04-04" "2005-07-24"
[17] "2005-11-12" "2006-03-03" "2006-06-22" "2006-10-11"
[21] "2007-01-30" "2007-05-21" "2007-09-09" "2007-12-29"
[25] "2008-04-18" "2008-08-07"

3.6.2. 时间序列数据格式的转换

我们用ts函数可以很方便的把数据变成时间序列的数据:

> ls <- round(runif(50, 0, 100))
> ls
 [1]  19  15  41   7  33   6  30  89  75  38   5  45  14  24
[15]  55   6  32  25  60  85  49  63  23  98  78  99  25  73
[29]  15  33  26  68  30  90  99  91  27  39  49  83  81  83
[43]  60  72  38  30  60 100  17  27
> ts(ls, start = c(2012, 8), end = c(2016, 8), frequency = 12)
     Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2012                              19  15  41   7  33
2013   6  30  89  75  38   5  45  14  24  55   6  32
2014  25  60  85  49  63  23  98  78  99  25  73  15
2015  33  26  68  30  90  99  91  27  39  49  83  81
2016  83  60  72  38  30  60 100  17                
> ts(ls, start = c(2012, 4), end = c(2016, 4), frequency = 4)
     Qtr1 Qtr2 Qtr3 Qtr4
2012                  19
2013   15   41    7   33
2014    6   30   89   75
2015   38    5   45   14
2016   24   55    6   32
> ts(ls, start = c(2012), end = c(2016), frequency = 1)
Time Series:
Start = 2012 
End = 2016 
Frequency = 1 
[1] 19 15 41  7 33

在上面frequency中取值为12、4、1,分别对应为月、季度、年(很好记,就是月、季度、年的数量)。我们一般不以天来计算。

但是有可能出的是什么问题呢?就是取值为12、4、1的参数意义不完全一样,在这里解析一下:

> ts(ls, start = c(2012, 8), end = c(2016, 8), frequency = 12)
# 这里的参数表示月份和第几个月
> ts(ls, start = c(2012, 4), end = c(2016, 4), frequency = 4)
# 这里的参数表示月份和第几个季度,如果超过四,就忘下一年算,如2012、8,就是2013年的第四季度
> ts(ls, start = c(2012), end = c(2016), frequency = 1)
# 这里的参数表示年份,如果多加了一个参数,就会往后按加的数字移动相应的年份

4. 缺失数据的处理

4.1. NA

为啥会有缺失数据?很正常,要么是故障导致的数据丢失,要么就是根本没有收集这种数据。我们在R中统一使用NA表示缺失值。

这里特别讲一下缺失值:缺失值是指不知道的值, 表示没有数据,可能是0也可能是其他任何的值。什么意思呢?看我例子:

> 1 + NA # 1+不知道的值,也不知道是多少
[1] NA
> NA == 0 # 不知道的值,不知道是不是等于0
[1] NA

所以在我们对NA进行处理的时候永远都是NA,这就会给我们造成很多麻烦。比如我们在这里举个例子:

> sum(c(0, 1:50)) # 求0~50的和
[1] 1275
> sum(c(NA, 1:50)) # 把0换成NA求和
[1] NA

这里我们经常就得不到想要的结果,因为我们大多数时候是想要不管NA继续计算1~50的和的,所以为了这样计算,我们可以这样处理:

> sum(c(NA, 1:50), na.rm = T) # 将NA的数据都移除
[1] 1275
> mean(c(NA, 1:50), na.rm = T) # 求中位数
[1] 25.5

同时我们还可以从上面知道,我们求平均数的时候,用的是1到50的和,除以的也是50。代表了在计算的时候,我们是彻底没有管过NA。

我们已经初步了解了NA是什么,然后我们要在数据中判断NA是否存在,我们怎么做呢?其实R中内置了很多is函数,我们可以使用is函数判断很多数据类型,我们来试一试:

> library(VIM) # 加载VIM包,没有就下,下的不成功看安装教程,win应该下的很轻松
VIM is ready to use.

Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues

Attaching package: ‘VIM’

The following object is masked from ‘package:datasets’:

    sleep

> head(sleep)
   BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp
1 6654.000   5712.0   NA    NA   3.3 38.6  645    3   5
2    1.000      6.6  6.3   2.0   8.3  4.5   42    3   1
3    3.385     44.5   NA    NA  12.5 14.0   60    1   1
4    0.920      5.7   NA    NA  16.5   NA   25    5   2
5 2547.000   4603.0  2.1   1.8   3.9 69.0  624    3   5
6   10.550    179.5  9.1   0.7   9.8 27.0  180    4   4
  Danger
1      3
2      3
3      1
4      3
5      4
6      4
> head(is.na(sleep))
     BodyWgt BrainWgt  NonD Dream Sleep  Span  Gest  Pred
[1,]   FALSE    FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
[2,]   FALSE    FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[3,]   FALSE    FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
[4,]   FALSE    FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE
[5,]   FALSE    FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[6,]   FALSE    FALSE FALSE FALSE FALSE FALSE FALSE FALSE
       Exp Danger
[1,] FALSE  FALSE
[2,] FALSE  FALSE
[3,] FALSE  FALSE
[4,] FALSE  FALSE
[5,] FALSE  FALSE
[6,] FALSE  FALSE

然后可以发现,sleep这个数据集里面是有很多NA值的,这个时候我们如果去计算行列的总和就会发生很多问题:

> colSums(sleep)
 BodyWgt BrainWgt     NonD    Dream    Sleep     Span 
12324.98 17554.32       NA       NA       NA       NA 
    Gest     Pred      Exp   Danger 
      NA   178.00   150.00   162.00 
> rowSums(sleep)
 [1]       NA   77.700       NA       NA 7862.800  428.650
 [7]   96.723  776.800  152.900  794.560  163.825 1221.800
[13]       NA       NA   66.575  129.200   79.685  163.000
[19]       NA       NA       NA  333.260   55.820       NA
[25]  778.400       NA   77.701  110.540 1578.800       NA
[31]       NA   53.445  117.060 1768.000       NA       NA
[37]   57.023   65.978   67.800  179.600       NA  207.980
[43]  349.000   75.420  542.800   95.400       NA   61.280
[49]  139.035  405.000  264.250  274.400       NA  424.100
[55]       NA       NA   99.600  239.600   89.504  327.790
[61]   67.200       NA

对吧,里面有很多值就是NA,要计算简单,在函数里面加上na.rm为真就好了,但是我们是怎么处理这些数据的呢?这里我们可以用到na.omit函数,这个函数可以将有NA的数据集去除NA:

> na.omit(c(1:5, NA, 6:10, NA))
 [1]  1  2  3  4  5  6  7  8  9 10
attr(,"na.action")
[1]  6 12
attr(,"class")
[1] "omit"
> na.omit(sleep)
    BodyWgt BrainWgt NonD Dream Sleep  Span  Gest Pred Exp
2     1.000     6.60  6.3   2.0   8.3   4.5  42.0    3   1
5  2547.000  4603.00  2.1   1.8   3.9  69.0 624.0    3   5
6    10.550   179.50  9.1   0.7   9.8  27.0 180.0    4   4
7     0.023     0.30 15.8   3.9  19.7  19.0  35.0    1   1
8   160.000   169.00  5.2   1.0   6.2  30.4 392.0    4   5
9     3.300    25.60 10.9   3.6  14.5  28.0  63.0    1   2
10   52.160   440.00  8.3   1.4   9.7  50.0 230.0    1   1
11    0.425     6.40 11.0   1.5  12.5   7.0 112.0    5   4
12  465.000   423.00  3.2   0.7   3.9  30.0 281.0    5   5
15    0.075     1.20  6.3   2.1   8.4   3.5  42.0    1   1
16    3.000    25.00  8.6   0.0   8.6  50.0  28.0    2   2
17    0.785     3.50  6.6   4.1  10.7   6.0  42.0    2   2
18    0.200     5.00  9.5   1.2  10.7  10.4 120.0    2   2
22   27.660   115.00  3.3   0.5   3.8  20.0 148.0    5   5
23    0.120     1.00 11.0   3.4  14.4   3.9  16.0    3   1
25   85.000   325.00  4.7   1.5   6.2  41.0 310.0    1   3
27    0.101     4.00 10.4   3.4  13.8   9.0  28.0    5   1
28    1.040     5.50  7.4   0.8   8.2   7.6  68.0    5   3
29  521.000   655.00  2.1   0.8   2.9  46.0 336.0    5   5
32    0.005     0.14  7.7   1.4   9.1   2.6  21.5    5   2
33    0.010     0.25 17.9   2.0  19.9  24.0  50.0    1   1
34   62.000  1320.00  6.1   1.9   8.0 100.0 267.0    1   1
37    0.023     0.40 11.9   1.3  13.2   3.2  19.0    4   1
38    0.048     0.33 10.8   2.0  12.8   2.0  30.0    4   1
39    1.700     6.30 13.8   5.6  19.4   5.0  12.0    2   1
40    3.500    10.80 14.3   3.1  17.4   6.5 120.0    2   1
42    0.480    15.50 15.2   1.8  17.0  12.0 140.0    2   2
43   10.000   115.00 10.0   0.9  10.9  20.2 170.0    4   4
44    1.620    11.40 11.9   1.8  13.7  13.0  17.0    2   1
45  192.000   180.00  6.5   1.9   8.4  27.0 115.0    4   4
46    2.500    12.10  7.5   0.9   8.4  18.0  31.0    5   5
48    0.280     1.90 10.6   2.6  13.2   4.7  21.0    3   1
49    4.235    50.40  7.4   2.4   9.8   9.8  52.0    1   1
50    6.800   179.00  8.4   1.2   9.6  29.0 164.0    2   3
51    0.750    12.30  5.7   0.9   6.6   7.0 225.0    2   2
52    3.600    21.00  4.9   0.5   5.4   6.0 225.0    3   2
54   55.500   175.00  3.2   0.6   3.8  20.0 151.0    5   5
57    0.900     2.60 11.0   2.3  13.3   4.5  60.0    2   1
58    2.000    12.30  4.9   0.5   5.4   7.5 200.0    3   1
59    0.104     2.50 13.2   2.6  15.8   2.3  46.0    3   2
60    4.190    58.00  9.7   0.6  10.3  24.0 210.0    4   3
61    3.500     3.90 12.8   6.6  19.4   3.0  14.0    2   1
   Danger
2       3
5       4
6       4
7       1
8       4
9       1
10      1
11      4
12      5
15      1
16      2
17      2
18      2
22      5
23      2
25      1
27      3
28      4
29      5
32      4
33      1
34      1
37      3
38      3
39      1
40      1
42      2
43      4
44      2
45      4
46      5
48      3
49      1
50      2
51      2
52      3
54      5
57      2
58      3
59      2
60      4
61      1

我们看到我们删除向量中NA的时候成功删除了,还多了删除的位置。删除数据框的时候也成功了,而且把含有NA的这一行也全部删除了:

> length(rownames(sleep))
[1] 62
> length(rownames(na.omit(sleep)))
[1] 42

4.2. 各种缺失数据

  • NA:未知的值;
  • NAN:不存在的值,如tan90;
  • inf:无穷值,如1/0。

也可以像is.na一样,用is.nan和is.inf来判断。


ps:

R中包含了高效用于处理缺失值的包,如VIM包等,详细的可以再去学,基础这里就不介绍了。

5. 字符串的处理

R处理字符串用的最多的就是正则表达式,但是处理文本用python也挺好的,这里可以不用R

5.1. 基础的字符串处理函数

我们看下面的代码,简单学几个函数:

> nchar('Hello, World!') # 统计字符串长度
[1] 13
> month.name
 [1] "January"   "February"  "March"     "April"    
 [5] "May"       "June"      "July"      "August"   
 [9] "September" "October"   "November"  "December" 
> nchar(month.name) # 统计字符串向量每个字符串长度
 [1] 7 8 5 5 3 4 4 6 9 7 8 8
> length(month.name) # 我才是用来统计向量长度的
[1] 12
> paste('han', 'han') # 连接字符串
[1] "han han"
> paste('han', 'han', sep = '') # 也可以设置连接符
[1] "hanhan"
> paste(month.name, 'hanhan') # 向量中的每个字符串与字符串相连
 [1] "January hanhan"   "February hanhan"  "March hanhan"    
 [4] "April hanhan"     "May hanhan"       "June hanhan"     
 [7] "July hanhan"      "August hanhan"    "September hanhan"
[10] "October hanhan"   "November hanhan"  "December hanhan"
> substr(month.name, 1, 3) # 截取字符串,从1开始,取3个
 [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep"
[10] "Oct" "Nov" "Dec"
> month.abb
 [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep"
[10] "Oct" "Nov" "Dec"
> toupper(month.abb) # 全转大写
 [1] "JAN" "FEB" "MAR" "APR" "MAY" "JUN" "JUL" "AUG" "SEP"
[10] "OCT" "NOV" "DEC"
> tolower(month.abb) # 全转小写
 [1] "jan" "feb" "mar" "apr" "may" "jun" "jul" "aug" "sep"
[10] "oct" "nov" "dec"
> str <- 'I am hanhan'
> strsplit(str, ' ') # 按自定义分割符,分割字符串
[[1]]
[1] "I"      "am"     "hanhan"

> strsplit(c(str, str, str), ' ') # 分割多个字符串
[[1]]
[1] "I"      "am"     "hanhan"

[[2]]
[1] "I"      "am"     "hanhan"

[[3]]
[1] "I"      "am"     "hanhan"

> face <- 1: 13
> suit <- c('spades', 'clubs', 'hearts', 'diamonds')
> outer (suit, face, FUN = paste) # 笛卡尔积,采用连接函数
     [,1]         [,2]         [,3]         [,4]        
[1,] "spades 1"   "spades 2"   "spades 3"   "spades 4"  
[2,] "clubs 1"    "clubs 2"    "clubs 3"    "clubs 4"   
[3,] "hearts 1"   "hearts 2"   "hearts 3"   "hearts 4"  
[4,] "diamonds 1" "diamonds 2" "diamonds 3" "diamonds 4"
     [,5]         [,6]         [,7]         [,8]        
[1,] "spades 5"   "spades 6"   "spades 7"   "spades 8"  
[2,] "clubs 5"    "clubs 6"    "clubs 7"    "clubs 8"   
[3,] "hearts 5"   "hearts 6"   "hearts 7"   "hearts 8"  
[4,] "diamonds 5" "diamonds 6" "diamonds 7" "diamonds 8"
     [,9]         [,10]         [,11]         [,12]        
[1,] "spades 9"   "spades 10"   "spades 11"   "spades 12"  
[2,] "clubs 9"    "clubs 10"    "clubs 11"    "clubs 12"   
[3,] "hearts 9"   "hearts 10"   "hearts 11"   "hearts 12"  
[4,] "diamonds 9" "diamonds 10" "diamonds 11" "diamonds 12"
     [,13]        
[1,] "spades 13"  
[2,] "clubs 13"   
[3,] "hearts 13"  
[4,] "diamonds 13"
> outer (suit, face, FUN = paste, sep = '--') # 既然用了连接函数,自然也可以换连接符
     [,1]          [,2]          [,3]          [,4]         
[1,] "spades--1"   "spades--2"   "spades--3"   "spades--4"  
[2,] "clubs--1"    "clubs--2"    "clubs--3"    "clubs--4"   
[3,] "hearts--1"   "hearts--2"   "hearts--3"   "hearts--4"  
[4,] "diamonds--1" "diamonds--2" "diamonds--3" "diamonds--4"
     [,5]          [,6]          [,7]          [,8]         
[1,] "spades--5"   "spades--6"   "spades--7"   "spades--8"  
[2,] "clubs--5"    "clubs--6"    "clubs--7"    "clubs--8"   
[3,] "hearts--5"   "hearts--6"   "hearts--7"   "hearts--8"  
[4,] "diamonds--5" "diamonds--6" "diamonds--7" "diamonds--8"
     [,9]          [,10]          [,11]         
[1,] "spades--9"   "spades--10"   "spades--11"  
[2,] "clubs--9"    "clubs--10"    "clubs--11"   
[3,] "hearts--9"   "hearts--10"   "hearts--11"  
[4,] "diamonds--9" "diamonds--10" "diamonds--11"
     [,12]          [,13]         
[1,] "spades--12"   "spades--13"  
[2,] "clubs--12"    "clubs--13"   
[3,] "hearts--12"   "hearts--13"  
[4,] "diamonds--12" "diamonds--13"

5.2. 正则表达式

先举个例子,我们要将一个全小写的月份改成首字母大写。我们这时候可以使用到subgsub函数。差别是什么呢?sub是一次替换,gsub是全局替换。

> gsub('^(\\w)', '\\U\\1', tolower(month.abb)) # 正则替换,gsub(被替换的串,替换的串,原串)
 [1] "Ujan" "Ufeb" "Umar" "Uapr" "Umay" "Ujun" "Ujul" "Uaug"
 [9] "Usep" "Uoct" "Unov" "Udec"
> gsub('^(\\w)', '\\U\\1', tolower(month.abb), perl = T) # 我们是perl类型正则表达式,所以需要perl=T
 [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep"
[10] "Oct" "Nov" "Dec"
> gsub('^(\\w)', '\\L\\1', toupper(month.abb), perl = T) # 同理小写
 [1] "jAN" "fEB" "mAR" "aPR" "mAY" "jUN" "jUL" "aUG" "sEP"
[10] "oCT" "nOV" "dEC"

除了gsub的匹配函数,我们也常用grepmatch函数,这两个又有什么差别呢?很简单,就是grep可以用正则,match函数只能直接匹配:

> cmp
[1] "han+"     "hanhan"   "handsome" "def"     
> grep('han+', cmp) # 正则查找
[1] 1 2 3
> grep('han+', cmp, fixed = F) # fixed=F表示可以正则
[1] 1 2 3
> grep('han+', cmp, fixed = T) # 关闭正则
[1] 1
> match('han+', cmp) # 查找'han+'字符串,无正则
[1] 1
> match('han', cmp) # 查找'han'字符串,没有,因为match类似于%in%
[1] NA

6. 数据的读写

6.1. 手动写入

手写数据是最无聊也是最工具人的操作了,其实做几个变量,并且转换为数据框就完成了,没有啥技术性:

> # 输入病例数据变量
> PaientID <- c(1: 4)
> AdmDate <- c('10/15/2009', '11/01/2009', '10/21/2009', '10/28/2009')
> Age <- c(25, 34, 28, 52)
> Diabetes <- c('Type1', 'Type2', 'Type1', 'Type1')
> Status <- c('Poor', 'Improved', 'Excellent', 'Poor')

> # 根据变量构造数据框
> dop <- data.frame(PaientID, AdmDate, Age, Diabetes, Status) 
> dop
  patientID    admdate age diabetes    status
1         1 10/15/2019  25    Type1      Poor
2         2 11/01/2009  34    Type2  Improved
3         3 10/21/2009  28    Type1 Excellent
4         4 10/28/2009  52    Type1      Poor

然后就要讲到一个操作,也就是和Excel一样的图形化界面(不过完全没有Excel好用,不如在Excel里做好了再导入R):

data <- edit(data)

保存只要关闭退出就好咯,但是edit是返回一个结果,所以必须要赋值给一个新的变量哦。

然后这里必须要备注一下了,win系统当然是可以直接打开的,但是Mac用户会发现我们无法运行。因为Mac系统缺乏这样一个图形化的界面环境,所以要先下载一个软件(XQuartz)才能开始使用,下完只要运行指令就会自动调用这个软件咯(第二个让我更愿意Excel的原因是,这个软件界面挺丑der,用着还不舒服)。

6.2. 采用数据库的读取方法

数据库读取可以使用一些数据库的库进行连接,但由于为不用数据库连接,目前也没用常用数据库,所以要用到以后再来补档。

辛酸故事:我是想下RODBC包进行连接我的mysql数据库试试的,但我试试就逝世了。我根本安装不上,正如我的R包安装血泪史一样。所以我暂时放弃了。

6.3. 采用本地文件的读取方法

6.3.1. 读取txt文件

读取txt文件,首先需要有一个txt文件,所以在这我先给出一个文件:

将这个文件读入,我们只需要进行下面的操作,因为对于普通的txt文件R默认是有读入方法的,所以不用下载包:

> df <- read.table('./MyData/input.txt')
> head(df) # 技巧,默认用于显示data.frame前6行
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6
> tail(df) # 我当然也可以尾6行
    Ozone Solar.R Wind Temp Month Day
148    14      20 16.6   63     9  25
149    30     193  6.9   70     9  26
150    NA     145 13.2   77     9  27
151    14     191 14.3   75     9  28
152    18     131  8.0   76     9  29
153    20     223 11.5   68     9  30
> head(df, 3) # 或者我只想看3行
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3

这里要注意一下就是我的文件是放在默认目录下的,所以我用的相对路径。

但除了上面这种用空格隔开数据的txt文本数据,我们在很早也常用csv文件,csv文件很简单,就相当于是将我们上面看见的这种txt文本文件的数据用逗号隔开罢了:

所以读入的时候和读取txt文件用的是同一个函数(或者直接用读csv的函数),但是读入有个什么限制呢?很容易理解,就是我们需要用逗号分隔罢了:

> df <- read.table('./MyData/input.csv') # 直接读的错误读法
> head(df)
                 V1
1                  
2         Mazda RX4
3     Mazda RX4 Wag
4        Datsun 710
5    Hornet 4 Drive
6 Hornet Sportabout
                                                                   V2
1 ,"mpg","cyl","disp","hp","drat","wt","qsec","vs","am","gear","carb"
2                                ,21,6,160,110,3.9,2.62,16.46,0,1,4,4
3                               ,21,6,160,110,3.9,2.875,17.02,0,1,4,4
4                              ,22.8,4,108,93,3.85,2.32,18.61,1,1,4,1
5                            ,21.4,6,258,110,3.08,3.215,19.44,1,0,3,1
6                             ,18.7,8,360,175,3.15,3.44,17.02,0,0,3,2
> df <- read.table('./MyData/input.csv', sep = ',') # 我们将分隔符改为逗号,读入正确,但是列号错了
> head(df)
                 V1   V2  V3   V4  V5   V6    V7    V8 V9 V10
1                    mpg cyl disp  hp drat    wt  qsec vs  am
2         Mazda RX4   21   6  160 110  3.9  2.62 16.46  0   1
3     Mazda RX4 Wag   21   6  160 110  3.9 2.875 17.02  0   1
4        Datsun 710 22.8   4  108  93 3.85  2.32 18.61  1   1
5    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1   0
6 Hornet Sportabout 18.7   8  360 175 3.15  3.44 17.02  0   0
   V11  V12
1 gear carb
2    4    4
3    4    4
4    4    1
5    3    1
6    3    2
> df <- read.table('./MyData/input.csv', sep = ',', header = T) # 加上了同意将第一行作为列号
> head(df)
                  X  mpg cyl disp  hp drat    wt  qsec vs am
1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1
2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1
3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1
4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0
5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0
6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0
  gear carb
1    4    4
2    4    4
3    4    1
4    3    1
5    3    2
6    3    1
> df <- read.csv('./MyData/input.csv') # 或者直接用读csv的函数
> head(df)
                  X  mpg cyl disp  hp drat    wt  qsec vs am
1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1
2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1
3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1
4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0
5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0
6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0
  gear carb
1    4    4
2    4    4
3    4    1
4    3    1
5    3    2
6    3    1

这个函数中还有许多参数可以使用,例如skip参数可以用于跳过前面指定数量的行,nrow用于确定读取的行数,配合可以取得某一段的数据。这些都可以使用?read.table去查看参数的使用方法。还有比如na.string,用于确定数据中的缺失值,因为一个数据集中的缺失值不一定都表示为NA,比如为nothing,我们就可以用这个参数将这个符号替换为缺失值。

我们在上面使用了read.csv的方法,其实这个方法和read.table没有本质的差别,主要就是改了一个分隔符,都是从read.table演变而来的。还有read.fwf用来确定每一个变量的占位长度。都可以查阅文档(read.fwf用的少就不讲)。

除此之外还有用于提取剪切板的方法,我们也可以在剪切板中保存数据并读取,在这里Mac用户和win用户就有差别了,因为两边的剪切板表达方式不太一样:

> df <- read.csv(pipe('pbpaste')) # Mac
> df
                  X  mpg cyl disp  hp drat    wt  qsec vs am
1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1
2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1
3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1
4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0
5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0
6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0
7        Duster 360 14.3   8  360 245 3.21 3.570 15.84  0  0
  gear carb
1    4    4
2    4    4
3    4    1
4    3    1
5    3    2
6    3    1
7    3    4
> df <- read.csv('clipboard') # win
> df <- readClipboard() # win

还有一些别的函数用于读取,不过多讲解,就演示一下:

> readLines('./MyData/input.csv', n = 5) # 用字符串读出指定行数
[1] "\"\",\"mpg\",\"cyl\",\"disp\",\"hp\",\"drat\",\"wt\",\"qsec\",\"vs\",\"am\",\"gear\",\"carb\""
[2] "\"Mazda RX4\",21,6,160,110,3.9,2.62,16.46,0,1,4,4"                                            
[3] "\"Mazda RX4 Wag\",21,6,160,110,3.9,2.875,17.02,0,1,4,4"                                       
[4] "\"Datsun 710\",22.8,4,108,93,3.85,2.32,18.61,1,1,4,1"                                         
[5] "\"Hornet 4 Drive\",21.4,6,258,110,3.08,3.215,19.44,1,0,3,1" 

6.3.2. 读取html网页表格

html网页表格本就是为了让用户进行阅读才放的文件,可以用XML以及多个包进行提取,但是不建议这样搞,所以略了略了

一切花里胡哨格式的文件都建议先转换为Excel文件再进行读取。

6.3.3. 写入txt类文件

其实写入和读取没有太大的差别,我们直接上例子:

> df <- read.csv('./MyData/input.csv')
> head(df)
                  X  mpg cyl disp  hp drat    wt  qsec vs am
1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1
2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1
3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1
4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0
5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0
6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0
  gear carb
1    4    4
2    4    4
3    4    1
4    3    1
5    3    2
6    3    1
> write.table(df, 'test.txt')
> write.csv(df, 'test.csv')

下面是我们输出的txt和csv文件:

可以看到我们都正常的写入了,当然写个啥列表什么的也没问题咯:

> cat(rivers) # 用过终端的同志们应该很熟悉了,用来将文本打到屏幕上
735 320 325 392 524 450 1459 135 465 600 330 336 280 315 870 906 202 329 290 1000 600 505 1450 840 1243 890 350 407 286 280 525 720 390 250 327 230 265 850 210 630 260 230 360 730 600 306 390 420 291 710 340 217 281 352 259 250 470 680 570 350 300 560 900 625 332 2348 1171 3710 2315 2533 780 280 410 460 260 255 431 350 760 618 338 981 1306 500 696 605 250 411 1054 735 233 435 490 310 460 383 375 1270 545 445 1885 380 300 380 377 425 276 210 800 420 350 360 538 1100 1205 314 237 610 360 540 1038 424 310 300 444 301 268 620 215 652 900 525 246 360 529 500 720 270 430 671 1770
> write(rivers, 'rivers.txt')

是吧,莫得问题~

但是在对csv文件进行操作的时候有一个很大的问题,我们来看一下:

> df <- read.csv('test.csv')
> head(df)
  X.1                 X  mpg cyl disp  hp drat    wt  qsec vs
1   1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0
2   2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0
3   3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1
4   4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1
5   5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0
6   6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1
  am gear carb
1  1    4    4
2  1    4    4
3  1    4    1
4  0    3    1
5  0    3    2
6  0    3    1
> write.csv(df, 'test.csv')
> df <- read.csv('test.csv')
> head(df)
  X.2 X.1                 X  mpg cyl disp  hp drat    wt  qsec
1   1   1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46
2   2   2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02
3   3   3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61
4   4   4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44
5   5   5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02
6   6   6           Valiant 18.1   6  225 105 2.76 3.460 20.22
  vs am gear carb
1  0  1    4    4
2  0  1    4    4
3  1  1    4    1
4  1  0    3    1
5  0  0    3    2
6  1  0    3    1

我们会发现,我们每次对csv文件进行一次读写,就对多一列行号,为啥呢?因为每次都会把行号当成数据列读进去又当成数据读出来呀。反复几次就多了很多多余的东西了。

我们这么解决:

> head(df) # 先有一份最原始的数据
                  X  mpg cyl disp  hp drat    wt  qsec vs am
1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1
2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1
3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1
4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0
5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0
6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0
  gear carb
1    4    4
2    4    4
3    4    1
4    3    1
5    3    2
6    3    1
> write.csv(df, 'test.csv', row.names = F) # 列名参数置否

就没问题了~

还有一些参数,像追加之类的:

> write.table(iris, 'test.csv', sep = ',', append = T) # 不覆盖表格并在后面添加

6.3.4. Excel文件的读写

第一种方法其实就是,把xlsx文件保存为txt或csv就可以了,用上面的txt类方法就可以读取了。当然读剪切板也行。

然后就是安装包直接对xlsx文件进行读写了,我一般使用openxlsx包,这个包简单方便(还有XLConnect包可以用,但是我Mac因为可能是java环境的问题装不上,我就放弃了):

> library(openxlsx)
> df <- read.xlsx('./MyData/data.xlsx') # 直接提取表格
> head(df)
                 X1  mpg cyl disp  hp drat    wt  qsec vs am
1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1
2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1
3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1
4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0
5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0
6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0
  gear carb
1    4    4
2    4    4
3    4    1
4    3    1
5    3    2
6    3    1
> write.xlsx(df, 'test.xlsx') # 直接写入表格

当然还有一些参数可以用咯,我们来康康,因为不难,所以不逐个解析:

> df <- read.xlsx('./MyData/data.xlsx', colNames = F) # 不把第一行作为列明
> head(df, 3)
             X1   X2  X3    X4    X5   X6    X7    X8  X9 X10
1          <NA>  mpg cyl  disp    hp drat    wt  qsec  vs  am
2     Mazda RX4 21.0 6.0 160.0 110.0  3.9  2.62 16.46 0.0 1.0
3 Mazda RX4 Wag 21.0 6.0 160.0 110.0  3.9 2.875 17.02 0.0 1.0
   X11  X12
1 gear carb
2  4.0  4.0
3  4.0  4.0
> df <- read.xlsx('./MyData/data.xlsx', rowNames = T) # 将第一列作为行名
> head(df, 3)
               mpg cyl disp  hp drat    wt  qsec vs am gear
Mazda RX4     21.0   6  160 110 3.90 2.620 16.46  0  1    4
Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4
Datsun 710    22.8   4  108  93 3.85 2.320 18.61  1  1    4
              carb
Mazda RX4        4
Mazda RX4 Wag    4
Datsun 710       1
> df <- read.xlsx('./MyData/data.xlsx', rows = c(8: 12), cols = c(1: 3), colNames = F) # 选取行列
> df
          X1   X2 X3
1 Duster 360 14.3  8
2  Merc 240D 24.4  4
3   Merc 230 22.8  4
4   Merc 280 19.2  6
5  Merc 280C 17.8  6
> write.xlsx(list(df, df), 'test.xlsx') # 输出为两个sheet 

其实原本Excel读取是可以多讲一点的,因为读取Excel分为多步骤和单步骤,多步骤有助于代码的理解,不过我没讲。

简单来说就是,读文件分为,建立对象,读取文件,读取表,读取数据;写对象分为,建立对象,写文件,写表,写数据。

但是作为应用知道怎么用就好啦。然后学过python的同志应该也会更了解,数据分析还是python比R好,所以要看就去康python吧。或者直接学Excel哈哈哈

6.3.5. R格式文件的读写

R格式的文件,很简单就能理解,是R专门的文件格式,好处是什么呢?很好理解,我们可以将数据原样的转移到文件里面。因为如果保存为别的格式的文件,总会有一些数据丢失的。

怎么存呢?就很简单:

> class(state.x77)
[1] "matrix" "array" 
> mx <- state.x77
> head(mx)
           Population Income Illiteracy Life Exp Murder
Alabama          3615   3624        2.1    69.05   15.1
Alaska            365   6315        1.5    69.31   11.3
Arizona          2212   4530        1.8    70.55    7.8
Arkansas         2110   3378        1.9    70.66   10.1
California      21198   5114        1.1    71.71   10.3
Colorado         2541   4884        0.7    72.06    6.8
           HS Grad Frost   Area
Alabama       41.3    20  50708
Alaska        66.7   152 566432
Arizona       58.1    15 113417
Arkansas      39.9    65  51945
California    62.6    20 156361
Colorado      63.9   166 103766
> saveRDS(mx, 'mx.RDS')

这样就成功存进去了,既然我刚刚说了可以不丢失的保存,那我们再读出来试试:

> mx <- readRDS("~/Documents/Rstudio/mx.RDS")
> class(mx)
[1] "matrix" "array" 
> head(mx)
           Population Income Illiteracy Life Exp Murder
Alabama          3615   3624        2.1    69.05   15.1
Alaska            365   6315        1.5    69.31   11.3
Arizona          2212   4530        1.8    70.55    7.8
Arkansas         2110   3378        1.9    70.66   10.1
California      21198   5114        1.1    71.71   10.3
Colorado         2541   4884        0.7    72.06    6.8
           HS Grad Frost   Area
Alabama       41.3    20  50708
Alaska        66.7   152 566432
Arizona       58.1    15 113417
Arkansas      39.9    65  51945
California    62.6    20 156361
Colorado      63.9   166 103766

没有任何问题~

关于R的数据文件,除了用于保存数据的.RDS,还有==.RData文件==,我们R的工作目录下就会自动生成的这个文件是啥呢?

其实.RData这个文件是用于保存我们工作区中变量的,同样,我们也可以自己制作以.RData为后缀的数据文件,同时使用时会自动加载这里面的数据。

> save(iris, file = 'iris.RData')
> load("~/Documents/Rstudio/iris.RData")

这就保存了想要的变量,然后保存全部的也很简单:

> save.image(file = 'all.RData')
> load("~/Documents/Rstudio/all.RData")

本章完~其他R内容同专栏更新

;