R语言入门学习篇一

R语言起源

R语言由新西兰奥克兰大学Ross Ihaka和Ribert Gentlenman两人共同发明,其词法和语法分别源自Scheme和S语言。

R定义:一个能够自由有效地用于统计计算和绘图的语言和环境,它提供了广泛的统计分析和绘图技术。

R语言的优势

  • 免费开源
  • 全面的统计研究平台,提供各种各专业的数据分析技术
  • 是一个程序设计语言,所以他的能力很容易通过使用用户定义的函数扩展
  • 拥有顶尖水准的制图功能
  • 开源从多个数据源获取数据并将其转换为可用的形式
  • 可运行在多种平台上

R的学习资源

  • R的主页 :http://www.r-project.org
  • CRAN:http://cran.r-project.org
  • R的博客(推荐多逛逛):http://www.r-bloggers.com
  • R的数据:《数据挖掘与R语言》、《R语言实战》

R的安装

下载:

进入R的主页http://www.r-project.org,找到download,选择一个镜像进入,然后选择适合自己电脑的版本进行下载

2.安装:

默认安装即可

R的基本使用/常用命令

变量是区分大小写的

r的赋值符号可以为=或者<-(更常用后者)

1
2
3
4
5
6
7
a <- 3  # 把3赋值给a

b <<- 2  # 强制赋值给全局变量b

s <- sum(1,2,3,4)
m <- mean(1,2,3,4)
m1 <- max(1,5,2,3)

查看和删除对象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 查看
ls()  #查看当前工作空间中已经使用的变量、函数等对象
ls.str() #列出全部及详细信息
ls(all.names = TRUE) #查看包含隐藏变量、函数等的全部对象

# 查看变量长度
length(a)

# 查看变量类型
mode(v)

# 删除对象
# 常量、变量、函数等都可以称为对象
rm(a)  #删除一个对象a(以节约空间)
rm(b,c) #删除多个对象b,c,...
rm(list = ls())  #删除所有对象


#查看命令com的变量格式
args(com)

向量的操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 求q中所有元素分别的平方根
y <- sqrt(a)

z <- a + a2  # 元素相加,长度不一致--->使得较短的向量不断重复循环


# 生成1到1000的向量
x <- 1:1000

# 生成序列,从1到20增量为3
seq(1,20,3)

# 生成向量,值为5,循环10次
rep(5,15)
rep(1:3, 3) # 1-3的序列,循环三次

x = rep(v, each = n)
#依次对向量v的每个元素复制n此生成新的向量x。


# 生成10个服从均值为0,标准差为1的向量
rnorm(10)

# 生成服从正态分布的6个均值为5,标准差为2的向量
rnorm(6, mean=5, sd=2)

# 取出大于0的
x <- c(0, -3, 4, -1, 45, 98, 12)
x[x>0]
x[x>=2 | x<5]  # 取小于5,大于等于2的
x[-5] # 不取第五个值
x[-(1:3)]  # 不取第1-3元素





x = round(v)
#生成一个向量x,其中每个元素是v对应元素的最近整数。
 
> order(x)
#获得向量x第i大元素在向量中的位置。
 
> rank(x)
#获得向量x每个元素大小位置。
 
> sort(x)
#对向量x从小到大进行排序。降序:sort(x, decreasing = TRUE)。
 
> tapply(x,f,g)
#根据因子f对向量x分类执行函数g。
 
> split(x,f)
#向量x按因子f分类。
 
> diff(x)
#返回向量x的差分向量。
 
> cumsum(x)
#返回向量x的累加向量。

查看历史命令:

1
2
3
4
5
# 查看敲过的命令(默认保存在当前系统用户的.history文件里,我们也可以设置保存的其文件)
history

history(10)  #显示最近执行的10条命令
#请空Console窗口:ctrl+L

与逻辑型数据有关的基本操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 is.data.frame(x)
#判断是否对象x是数据框。类似命令有is.ts(x),is.numeric(x)等。
 
> all(x>a)
#判断是否对象x的每个元素都大于a。
 
> any(x>a)
#判断对象x的元素中是否存在一个大于a。
 
> x>y
#判断x的每个元素是否大于y的每个元素。
 
> x[x>a]
#向量x中大于a的元素组成的新向量。
 
> subset(x, x>a)
#向量x中大于a的元素组成的新向量。与上面例子的区别在于若向量元素里有NA,上面的例子会保留在结果中,而subset命令会剔除掉。
 
> which(x, x>a)
#返回向量中大于a的元素的位置。
 
> x = ifelse(b, u, v)
#生成一个与b(逻辑向量)维度相同的数值向量,若b[i]为TRUE,则x[i]为u,反之为v

一个简单例子:

https://geoer666-1257264766.cos.ap-beijing.myqcloud.com/%E8%AE%A4%E8%AF%86R%E7%9A%84%E5%B0%8F%E4%BE%8B%E5%AD%901.png

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
age <- c(1,3,5,2,11,9,3,9,12,3)
weight <- c(4.4,5.3,7.2,5.2,8.5,7.3,6.0,10.4,10.2,6.1)

#mean求平均值,sd求标准差
mean(weight)
sd(weight)
#查看关系,可以得到相关度
cor(age,weight)
#也可以用plot画图来说明
plot(age,weight)

# 查看R可以画的图
demo()
demo(graphics)

查看帮助文档:

1
2
3
4
5
# 查看帮助文档
help.start()  # 打开帮助文档的首页
help("mean")	# 查看某一命令的用法,mean{base}意思是mean属于base包
help(package="base")  # 查看包的信息
?mean   # 同上

**R的工作空间:是当前所有的变量都存放的位置

建议养成习惯:给每个项目单独设置一个工作空间

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 查看工作空间
getwd()

# 设置新的工作空间
setwd(dir="d://RProject/test1")

list.files()  #查看当前工作目录下的文件
dir()         #查看当前工作目录下的文件


save.image()  #保存工作空间,防止断电等外部因素

R包的使用

R的包(package)可以从:http://cran.r.project.org/web/packages下载。

R自带了一系列默认包(base、datasets、grephics、methods等)

包的使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#列出已安装的包。
library()
 
# 安装新的包
install.packages("car")

# 查看包的信息
help(package="car") 


# 使用包--->需要先再入,有下面两种方式
library(ggplot)  
require(ggplot)

# 更新包
update.packages()




library(help = AER)
#获取包AER的信息。
 
detach(package:zoo)
#去除载入的包zoo。
 
search(reshape)
#列出已载入的包。

一般对象的基本操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
objects()
ls()
#列出所有对象


mode(x)
#查看对象x的模式:空,数值,字符,逻辑,复数,列表,函数(NULL,numeric,character,logical,complex,list,function)。



class(x)
#查看对象x的类型:除了mode里列出的几种类型外,还有整数,矩阵,因子,阵列,数据框,时间序列(integer,matrix,factor,array,data frame,ts)等其他类型。mode主要用于区别数据存放的方式,而class是一种更细微的分类方式,比如矩阵,就是一种更“有序”的数据存放方式。此命令比mode常用


> as.matrix(x)
#把对象x转为矩阵型。
 
> as.numeric(x)
#把对象x转为数值型。
 
>as.factor(x)
#把对象x转化为因子型。
 
> str(x)
#查看对象x的结构。str是structure的缩写。
 
> rm(x)
#移除对象x。
 
> rm(list=ls(all=TRUE))
#移除所有对象。
 
>head(x)
#查看数据的前x行

结果的重用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#如下场景
# head 查看
head(mtcars)
# lm是线性回归
lm(mpg~wt, data=mtcars)  

# 我们通常使用变量来保存,实现了重用:
result <- lm(mpg~wt, data=mtcars) 
# summary查看
summary(result)
#然后就可以用来进一步分析和使用了

# predict预测回归的值
predict(result, mynewdata)

R如何处理大数据集:

r的运算都是基于内存的,但是对于很大的数据运算显然是不合适的:

  • R有专门用于大数据的分析报告,如lm()是做线性拟合的函数,而biglm()则能以内存搞笑的方式实现大型数据的线性模型拟合
  • R与大数据处理平台的结合,如RHadoop、RHive、RHipe等

数据集

按照某种格式来创建数据集,是任何数据分析的第一步:

  1. 选择一种数据结构来存储
  2. 将数据输入或导入这个数据结构中

向R中导入数据有很多方便的方法,可以手工输入数据,也可以从外部源导入数据,数据源可以是电子表格、文本文件、统计软件(SAS)和各类数据库等

数据集通常由数据构成的一个矩形数组,行表示记录,列表示属性(字段)。

R拥有许多用于存储数据的对象类型,包括向量、矩阵、数组、数据框和列表,这些数据结构在存储数据的类型、创建方式、定位和访问我中个别元素的方法等方面都有所不同。

列表:向量、矩阵、数组、数据库、列表

向量:

只能包括一种数据类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 向量
a <- c(1,3,5,7,-5)
a2 <- c("one", "two", "three")
a3 <- c(1,2,6,"three")  # 都强制转换变成字符串了

# 访问向量中元素
a2[2]
a[1:3]
a[c(1,3,4)]

# 修改元素值(R语言可以对变量中每一个元素直接进行操作)
a2[2] <- "four"

# 求q中所有元素分别的平方根
y <- sqrt(a)

z <- a + a2  # 元素相加,长度不一致--->使得较短的向量不断重复循环


# 生成1到1000的向量
x <- 1:1000

# 生成序列,从1到20增量为3
seq(1,20,3)

矩阵:

只能包括一种数据类型,二维的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
?matrix  # 查看矩阵的用法

## 创建矩阵
y = matrix(5:24,nrow=4,ncol=5) # 默认按列填充


## 创建矩阵
x=c(2,4,6,8)
rowname <- c("R1", "R2")
colname <- c("C1", "C2")

newMymatrix <- matrix(x, nrow=2,ncol=2,byrow=TRUE,dimnames=list(rowname,colname)) # 按行填充

newMymatrix2 <- matrix(x, nrow=2,ncol=2,dimnames=list(rowname,colname)) # 按列填充
# 通过下标进行元素选择
newMymatrix2[1,]    # 访问第一行
newMymatrix2[1,3]   # 访问第一行第三个元素
newMymatrix2[,3]   # 访问三列


M = rbind(X,Y)
#按行合并矩阵X和Y形成新矩阵M。(X和Y列数需相同)
 
M = cbind(X,Y)
#按列合并矩阵X和Y形成新矩阵M。(X和Y行数需相同)
 

diag(M)
#矩阵M的对角线元素形成的向量


#求矩阵M的特征值和特征向量。
eigen(M)$val
eigen(M)$vec
 

创建矩阵

数组:

维度是可以大于2的,元素也只能是一种类型的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
?array
# 先确定维度的名字,3x2x4的
dim1 <- c("A1", "A2", "A3")
dim2 <- c("B1", "B2")
dim3 <- c("C1", "C2", "C3", "C4")

# 创建数组,参数:数据,维度,维度名字
d <- array(1:24, c(3,2,4), dimname=list(dim1.dim2,dim3))

#选取元素
d[1,2,3]  # 选取第一行,第二列,第三个

数据框

可以存储多种类型的数据

数据框会是我们以后更经常遇到的一种结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 创建数据框   data <- data.frame(col1, col2, ...)

#例子:
id <- c(1,2,3,4)
age <- c(25,34,28,52)
itype <- c("Type1","Type2","Type3","Type2")
status <- c("poor", "Improved", "Excellent", "poor")

#下面 创建病例数据的数据框
patientsData <- dada.frame(id, age, itype, status)


#取数据
patientsData[1:2]  # 取第一列和第二列
patientsData[c("itype", "status")] # 根据列名取值
patientsData$age	# 使用$来取值
# attach函数将数据框加入搜索路径,以后直接输入列名来取值
attach(mtcars)
mgp
detach(mtchar)	# 从搜索路径移出
# with()函数功能同attach
with(mtcars, {
  ll <- mpg
  ll
})


fix(Data)
#编辑数据框Data

因子

1
2
3
4
itype <- c("Type1","Type2","Type3","Type2")

# factor将factor以数组形式存储,将Type1和1联系起来,将Type2和2联系起来
itype <- factor(itype)

待查资料

https://www.runoob.com/r/r-factor.html

列表

是较复杂的数据类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# myLi <- list(object1, object2, ...)

g <- "First list"
h <- c(23,45,66,997)
j <- matrix(1:10, nrow=2)
k <- c("one", "two", "three")
# 创建列表
myList <- list(g, h, j, k)  # 将前面4个对象将入list


# 访问list中元素(和其他数据类型有区别)
myList[[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
27
28
29
30
31
32
33
34
35
36
37
38
# 创建一个列表
myLi <- list(stu.id=1234,
            stud.name="Tom",
            stud.marks="12,3,14,25,66")


# 获取第一个元素 [[]] 获取值
myLi[[1]]
mode(myLi[[1]])

# [] 单括号 获取第一个成分的"键值",即子列表
myLi[1]
mode(myLi[1])

myLi$stud.id

# names   获取list中的“键”
names(myLi)
names(myLi) <- c("idid", "name", "marks") # 可以修改
#去掉列表L里的对象名
unname(L)


# 扩充元素
myLi$parents <- c("Mom1", "Baba1")
length(myLi)


# 删减成分
myLi <- myLi[-4]  # 删除第四个成分

# 合并列表
other <- list(age=19, gender="male")
lst <- c(myLi, other)


# unlist变列表中元素为向量的形式  
unlist(lst)  # 每个向量都有一个名称

R的数据源导入的方法

可导入的数据源:

1.键盘输入

1
2
3
4
5
6
7
#(实现保存)。不使用edit的话只是一个中间变量,关闭后会消失
# 使用edit
mydata <- edit(mydata)


# 使用fix(更简洁)
fix(mydata)

2.从文本文件导入

r默认只能读取ascii编码的(ANSI),utf8等会有问题

文本文件的格式每行字段间用逗号隔开的

使用read.table()读取

1
2
3
4
5
# 参数:txt位置,header为True会吧文件首行取下来作为标签,sep指定间隔符
data <- read.table("f:/data/q.txt",header=True,sep=",") # 路径不要有中文


head(data) # 查看数据

3.导入Excel数据

导入excel数据方式很多(如),但比较复杂,这里选择简便的方式:另存excel文件类型选择csv,并以逗号分隔,再read.csv()

目的是读入数据的结果,不在乎手段,所以越简单越好

4. ……

用户自定义的函数

格式:

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

实例1:获取系统时间,指定格式并输入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 定义了一个函数
# switch,如果形参type值为long,执行对应部分
mydate <- function(type){
  switch(type,	
        long = format(Sys.time(), "%A %B %d %Y"),
        short = format(Sys.time(), "%m-%d-%y"),
        cat(type, "is not reccongnized type\n")
        )
}

# 调用
mydate("long")
mydate("short")

实例2:求1….n的和

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sum <- function(num){
  
  for(i in 1:num){
    x <- x + i
  }
  return(x)
}

fix(sum) # 会进入编辑器中,打开后给x赋初值:在for循环前 x <- 0

# 调用
sum(10)

R访问MySQL数据库

准备工作步骤:

  1. 安装RODBC包:install.packages("RODBC")
  2. 在http://dev.mysql.com/downloads/connector/odbc 下载connectors ODBC(选择适合自己系统的),然后安装
  3. windows:控制面板->管理工具->数据源(ODBC)->双击->添加->选中mysql ODBC driver–>输入数据库信息

使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#加载库
library(RODBC)
myconn <- odbcConnect("RData", uid="root", pwd="123456") # 数据库名,用户名,密码

# 导入mysql数据到r中
data1 <- sqlFetch(myconn, "news") # 指定数据表

# 导入查询到的数据到r中
data2 <- sqlQuery(myconn, "select id,title,pubtime feom news")

# 关闭连接
close(myconn)

R的集成开发环境(IDE) - RStudio

RStudio使用C++开发,界面更加友好,功能更加强大。

我们先下载R,然后去官网下载免费版RStudio即可。

使用:

ctrl+s保存为.R结尾的文件

run:

https://geoer666-1257264766.cos.ap-beijing.myqcloud.com/rstudio%20run.png

画图:

会在右下角plot显示,还可以对图进行导出保存

History:

https://geoer666-1257264766.cos.ap-beijing.myqcloud.com/rstudio1.png

R程序和默认工作空间:

Tools–>option–>General-> R version 和Default working directory

导入/保存工作空间:

Session -> load / save workspace

新建/打开工程:

Project下面

导入数据集:

Tools –> Import Dataset

如何画图

简单的图画例子

数据集:

image-20220412211923345

画图:

1
2
3
4
dose = c(20,30,40,45,60)
drugA = c(16,20,27,40,60)
drugB = c(15,18,25,31,40)
plot(dose, drugA, type = "b")  #b表示既绘制点也绘制线

plot

图形参数的修改

线条、符号、颜色:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# par
opar = par(no.readonly=TRUE)  # 生成的图形就可以进行修改了
# 进行修改
par(lty=2, pch=17)  # 虚线和三角形
# 再继续画图
plot(dose, drugA, type = "b") 
# 恢复最开始修改之前的图形
par(opar)

# 指定符号和线条,使用较多
plot(dose, drugA, type = "b", lty=6, pch=19, lwd=3, cex=2) 
help(plot) # 但并不是全部绘图函数都支持这个参数,可以先查看绘图函数都支持啥参数

# 指定颜色 colors()返回所有颜色的名称
#col = "#FFFFF"
#col = "red"
col = rgb(25,155,60)
...
plot(dose, drugA, type = "b", lty=6, pch=19, col="blue", col.axis="red", col.lab="green") 

符号和线的参数

颜色的参数

文本属性

文本相关参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
dose = c(20,30,40,45,60)
drugA = c(16,20,27,40,60)
drugB = c(15,18,25,31,40)

#opar = par(no.readonly=TRUE)  
#par(lty=2, pch=17)

plot(dose, drugA, type = "b", font.lab=3, cex.lab=1.5, font.main=2)    # 标题的样式为2倍,字体为斜体,

# 查看pdf能用的字体
names(pdfFonts())

图形、边界尺寸

图形、边界尺寸参数

1
2
3
4
#opar = par(no.readonly=TRUE)  
#par(pin=c(4,3), mai=c(1,.5,1,.2))  # 4英寸宽,3英寸高;边界为下1左0.5上1右0.2英寸

#plot(dose, drugA, type = "b", lty=2, col="red",bg="green") 
1
2
3
4
5
6
7
# 添加标题和坐标轴
plot(dose, drugA, type = "b", lty=2, col="red",bg="green", main="药物A的反应曲线", sub="一个测试数据", xlab="剂量",ylab="病人的反应",xlim=c(0,60),ylim=c(0,70))  # xlim是横坐标的刻度


# 或者用title 函数来调价标题
title(main="我的标题", col.main="red")
title(sub="我的副标题", col.sub="green")

自定义坐标轴

坐标轴参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#plot(dose, drugA, type = "b",pch=12,col="red",mar=c(5,4,4,8)+0.1, yaxt="n", ann=FALSE) # mar是边界,  yaxt="n"禁用y轴刻度, ann=FALSE不会出现坐标轴默认的描述# 设置自己的参数

y = c(1,10)
x = y
z =  10/x

opar = par(no.readonly=TRUE)
par(mar=c(5,4,4,8)+0.1)
plot(x,y, type = "b",pch=12,col="red", yaxt="n", lty=3,ann=FALSE)

axis(2, at=y, labels=x, col.axis="blue", las=2) # 2表示在左边添加刻度, las=2表示垂直与坐标轴,at表示刻度线的位置,col.axis坐标轴颜色
# lines和plot差不多,不过是在原来图像上画一条线
lines(x,z,type = "b",pch=12,col="green", lty=2) # 4表示在右边添加刻度
axis(4, at=z,labels=round(z,digits=2), col.axis="black", las=2,cex.axis=.7)

次要刻度线

1
2
3
4
5
6
7
8
9
# 1.先下载并导入包
install.packages("Hmisc")
library(Hmisc)


# 使用
#以下面数据为例
plot(1:4, 1:4, type="b")
minor.tick(nx=2,ny=3,tick.ratio=0.5) # x轴分为几段,y轴分为几段,强度

参考线

1
2
3
# abline(h=value, v=value) h为水平线,v为垂直线
abline(h=2, col="red", lty=2) # 在水平第二个位置添加水平线
abline(v=2.5, col="red", lty=1) 

图例

图例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
opar = par(no.readonly=TRUE)
par(lwd=2, cex=1.5, font.lab=2)
#药物A的
plot(dose, drugA, type="b",pch=15,col="red",lty=1, ylim=c(0,60), main="药物A和药物B的对比", xlab="剂量", ylab="药物反应")

#药物B的,在原来图的基上画
lines(dose, drugB, type="b",pch=17,col="blue",lty=2)

#更改刻度
minor.tick(nx=5,ny=2,tick.ratio=0.5)

#图例
legend("topleft", inset=.05, title="类型", legend("A","B"), lty=c(1,2),pch=c(15,17),col=c("red","blue")) # 顺序要和前面一样,lty是线的类型,pch是点符号的类型,col是颜色

文本标注

想针对某个点进行标注的时候

文本标注

1
2
3
4
attach(mtcars)
plot(wt,mpg, main="车重和油耗关系", xlab="车重", xlab="油耗", pth=18,col="blue")

text(wt,mpg,row.names(mcars),cex=0.5, pos=4, col="red")

图形组合、图形布局的精细控制

R如何画图

图形组合:

 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
attach(mtcars)
opar <- par(no.readonly=TRUE)
# 设置为两行两列
par(mfrow=c(2,2)) 
#画第1个图
plot(wt,mpg,main="wt vs mpg")
#画第2个图
plot(wt,disp,main="wt vs disp")
#画第3个图
hist(wt,main="Histogram of wt")
#画第4个图
boxplot(wt,main="Boxplot of wt")
par(opar)
detach(mtcars)


# layout
# 两行两列,1,1,2,3第一行第一个和第二个是第一个图形,第二行第一列是第二个图形,第二行第二列是第三个图(相当于把矩阵的数字排列进去)
layout(martrix(c(1,1,2,3)), 2,2, byrow=TRUE)


# 精确控制每幅图像大小,使用width和和height.控制每列的宽度width=c(3,1)表示第一列占3/4
# 如果高度和宽度调整的不合适有可能图幅占不下显示不全

layout(martrix(c(1,1,2,3)), 2,2,width=c(3,1), height=c(1,2),byrow=TRUE)

一个图幅画放多个图

图形精细控制:

1
par(fig(0, 0.8, 0, 0.8), new=TRUE)  # 画布左下角位置是0,0,右上角为0.8,0.8,  new=TRUE会在图形上继续添加

画布坐标

R基本的数据管理

一个示例:

示例1

在数据框中创建新变量

1
2
3
4
5
6
mydada <- data.frame(x1=c(2,3,4,5), x2=c(2,5,7,9))

#求和(和的一列会加入数据框)
mydata$sumx <- mydata$x1 + mydata$x2
#求平均值
mydata$meanx <- (mydata$x1 + mydata$x2)/2

变量的重编码(把连续的数字变成某字符串)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#比如对上述例子的年龄进行重编码
#如:定义年龄为99的时候为空值
survey <- data.frame(......)
survey$age[survey$age == 99] <- Na

#如:定义年龄>75的时候定义为老年人
survey$age[survey$age > 75] <- "老年人"

#如:定义年龄<75并且>55的时候的时候定义为中年人
survey$age[survey$age > 55 & survey$age < 75] <- "中年人"

变量的重命名

1
2
3
4
5
# 可以通过fix 调用可视化界面修改
fix(survey)

# 也可以使用names()
names(survey)[6] <- "question1" # 数据框[第几个值]

处理缺失值(NA)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
x <- c(1,2,NA)
# is.na() 判断是否为空,返回bool
is.na(x)
is.na(survey[,6:10]) # 判断第6-10列中是否有空值

# 不能使用 x == NA 这种方式判断

# 返回缺失值的位置
which(is.na(A))

#计算数据集A的缺失值总数
sum(is.na(A))

# 对NA值进行删除
y <- sum(x, na.rm=TRUE) # y返回x的和,对NA值进行删除

# 这种会删除空值所在的一整行:
data <- na.omit(survey)

日期值的使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# as.Date() 将字符串转换为日期

mydate <- as.Date("2022-04-14") # "2022-04-14"


mydate1 <- c("04/14/2022", "04/13/2022")
date <- as.Date(mydate1, "%m/%d/%Y") # 自定义显示格式


# Sys.Date()   返回系统日期

# date()   返回系统日期+时间

# format()  格式化输出
today <- Sys.Date()
format(today, format="%B %d %Y")  # 自定义格式化输出

# 天数减法
startdate <- as.Date("2022-01-02")
enddate <- as.Date("2022-04-15")
days <- enddate - startdate

日期格式

数据类型的判断及转换

1
2
3
4
5
6
a <- c(2,5,7)
is.numeric(a)
is.vertor(a)

b <- as.character(a)
is.numeric(b)

类型判断及转换函数

数据排序

1
2
3
4
5
6
7
8
9
# order() 函数

data <- survey[order(survey$age),] # 以survey的age来排序,默认升序, 加逗号表示对行排序,不加逗号表示对列排序!!!

# 降序,加负号
data <- survey[-order(survey$age),] 


data2 <- survey[order(survey$gender, survey$age),] # 先按性别排序,再按年龄排序

数据集合并

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 列合并cbind()和merge()
x <- matrix(c(1,2,3,4,5,6,7,8,9), nrow=3, ncol=3)
y <- x
z <- cbind(x,y) # 合并x和y
# 或者用merge(根据字段k1进行连接,类似sql中的联合)
z1 <- merge(x,y, by="k1")



# 行合并  rbind()
# 前提:变量数目的列数必须相同

数据集子集的抽取

1
2
3
4
5
6
7
8
# 方式1:
q <- survey[,6:10]  # 选取第6-10列

# 方式2:去除某部分
x <- survey[,-2] # 去掉第二列

# 按照条件选取,显示q1到q4列
newdata <- subset(surver, age>=35 | age<24, select=c(q1,q2,q3,q4))

随机抽样函数

1
2
3
4
5

# sample()
sample(x, size, replace=FALSE) #  从x中抽取size个,replace=FALSE表示不放回抽样

mysample <- survey[sample(5,3,replace=FALSE),]

R的高级数据管理

数学函数

1
2
3
4
5
6
7
8
# abs()  求绝对值
# sqrt()  求平方根
# ceiling(x)  不小于x的最小整数
# floor(3.567)   不小于x的最大整数
# round(3.55)  四舍五入
# sin()  三角函数
# cos()
# log(10)  对数函数

统计函数

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

mean(x)  # 求均值

sum(x)

# 求均值也可以这样
n <- sum(x)/length(x)

# 求标准差
sd(x)
# 求方差
var(x)

# 求最大最小值
min(x)
max(x)

# 标准化
scale(x)  # 默认对向量x使用均值为0标准差为1的

概率函数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
x <- pretty(c(-3,3), 30)
y <- dnorm(x)  # 正态分布
plot(y)

# 随机正态分布函数:生成50个,均值为20,标准差为8的
rnorm(50mean=20, sd=8)

# 生成一个服从正态分布的伪随机函数
runif(5)

# 
set.seed(12) # 先设定种子数
runif(5)

# 其他函数

image-20220415093505576

字符处理函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# nchar()  统计字符数量
nchar("dddf")

# 根据索引提取
substr("sahiu", 3,5)


# 查找(从向量中查找a)
grep("a", c("b","a","c","t"))


#字符串中a替换为A
sub("a","A", "abcde")

# strsplit()在字符串分割
strsplit("abcde", "c") # 以c分割
strsplit("abcde", "")  # 每个字符单独分开

# 字符串连接
paste("Thec", "Her is me.")

# 大小写转换
toupper("abc")
tolower("ABC")

其他实用函数

1
2
3
4
5
length()	# 获取长度

rep(1:3, 5) # 将1到3重复5次

cat("hello") # 输出到屏幕上

将之前的函数应用于矩阵和数据框中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
a <- c(1,2,4,5,6)
round(a) # 对所有值取


b <- matrix(runif(12), nrow=3)
log(b) # 针对全体进行对数
mean(b)

# apply()  将函数范围应用到数据库或数组某个维度
c <- matrix(rnorm(12), nrow=6, ncol=5) # 5列6行的服从正态的
apply(c ,1, mean) # 对c矩阵,按行就平均值
apply(c ,2, mean) # 对c矩阵,按列就平均值

# lapply    sapply  针对列表的单独操作

重复和循环

循环:

1
2
3
4
5
6
7
# for
for(i in 1:5) print("hello")  # 循环1-5


# while
x <- 5
while(x > 0) {print("Hello"); x<- x-1} # 语句之间用分号

条件执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# if-else
if(x != 1) print("male") else print("female")


# ifelse  满足条件执行1,不满足执行2
ifelse(条件, 语句1, 语句2)



# switch
felling <- c("sad", "glad", "afraid")
for(i in felling)
    print(switch(i, glad = "我很开心", afraid = "害怕", sad="悲伤")  # 如果i等于glad...

转置

1
2
3
4
5
# T

cars <- mtcars[1:5, 1:4] # 取1-5行,1-4列
# 转置矩阵
t(cars)

其他内容课余时间多学

R的基本图形

条形图

本节例子需要使用vcd包进行演示,install.packages('vcd')

简单的条形图

barplot()

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

#barplot(height)  最简单的方式,指定高度,默认垂直
barplot(c(1,2,4,6,2,7))
barplot(c(1,2,4,6,2,7), horiz=TRUE) # 水平的图

# 示例数据:关节炎病人的治疗情况
#Arthritis
counts <- table(Arthritis$Improve)
barplot(counts)

堆砌、分组条形图

绘制的数据不再仅仅是一个向量,而是矩阵

堆砌条形图:

1
2
3
4
5
# barplot


counts <- table(Arthritis$Improve,Arthritis$Treatment) # 矩阵的形式
barplot(counts) # 默认是堆砌的条形图

堆砌

分组条形图:

1
barplot(counts, beside=TRUE)  # beside=TRUE  值是并列的,不是堆砌的

分组

均值条形图

1
2
3
4
5
6
7

# 使用数据集 state.region,  state.x77
head(state)
states <- data.frame(state.region, state.x77)
x <- aggregate(states$Illiteracy, by=list(state.region), FUN=mean) # 统计地区的文盲率

barplot(x$x, names.arg=x$Group.1) # 画图并指定坐标名字

均值

条形图的微调

1
2
3
4
5
par(mar=c(5,8,4,2)) # 指定绘图区域范围
counts <- table(Arthritis$Improve,Arthritis$Treatment) 
par(las=2) # 标签由竖的旋转为横的

barplot(counts, horiz=TRUE, cex.names=0.8, names.arg=c("没有治疗的","一些治疗的", "显著治疗的")) 

饼图

饼图:

pie()

饼图缺陷:无法明确比较谁大谁小或相差多少

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# pie(x, label) # 参数1是数值向量,参数2是各个扇形标签的向量


par(mfrow=c(2,2)) # 画图区域分为四部分

x <- c(10,12,4,16,8)
lab <- c("国家1","国家2","国家3", "国家4", "国家5")
pct <- rouund(x/sum(x)*100)
labl <- c(lab, " ", "pct", %, sep=" ") # 自定义拼接制作标签

pie(x, labl, col=rainbow(length(labl)),main="简要饼图") # 指定名称, col=rainbow指定颜色

3D饼图

1
2
3
4
# 借助包:plotrix
library(plotrix)

pie3D(x, labl, explode=0.1, main="3D饼图") # explode=0.1指定饼之间的裂隙

扇图: 扇图可以明确比较大小

1
fan.plot(x, labels=lab, main="扇图")

扇形

直方图

柱条组成的,特点:x轴上将值域分成等分的组

hist()函数

1
2
3
4
5
6

#hist(x)
x <- mtcars$mpg

# 最简单的直方图
hist(x)

最简单的直方图

1
2
hist(x, breaks=12, col="red", xlab="每英里加仑数")
# x轴上划分为12组

直方图2

1
2
3
4
5
6
7
8
#  freq=False则y轴上不显示频数而是概率密度
hist(x, freq=FALSE, breaks=12, col="green", xlab="每英里加仑数")

# 添加数值的噪声(如下图的小竖线)
rug(jitter(x))

# 添加轴虚线
lines(density(x), col="red", lwd=2) # lwd是线的宽度

核密度图

x轴展现是值,y轴是反映x轴值上密度的情况

可以很直观了解,比如不同条件下的变化情况

1
2
3
4
# 先用density处理
x <- density(mtcars$mpg)
#  生成核密度图
plot(x) 

描述4缸或6缸汽车不同的耗油量的对比:

1
2
3
4
5
attach(mtcars)

library(sm)
# 比较 sm.density.compare(x, factory)
sm.density.compare(mpg, cyl, xlab="英里每加仑")

对比

箱线图

分位数

箱线

**箱线图元素:**最小值、四分(之一)位数、中位数、四分(之三)为主、最大值、异常值

1
2
3
4
5
6
7
8
# boxplot()

boxplot(mtcars$mpg, main="箱线图", ylab="公里每加仑")
# 
boxplot(mpg~cyl, data=mtcars, main="箱线图", ylab="公里每加仑", xlab="汽缸数")

# 可以看到6缸的是比较稳定的(上下窄)
# 做质量检测的时候经常用到

箱线图

实例分析–预测海藻数量

预测海藻数量

1.问题描述与目标:

问题描述与目标

2.数据集的导入:

数据集的导入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 以上数据集在 DMwR 包中
install.packages("DMwR2")
library("DMwR2")

# 先了解一下数据
head(algae)
summary(algae)


# 这里可以查看一下化学属性的图形
hist(algae$mxPH, prob=T, ylim=0:1) # prob表示显示概率密度
lines(density(algae$mxPH, na.rm=T))

数据解读

3.数据预处理

数据缺失的处理

查找缺失值:

1
2
3
4
5
6
# 返回存在缺失值所在行的行数
algae[!complete.cases(algae), ]  

# 返回存在多个缺失值的位置
manyNAs(algae)
manyNAs(algae, 0.2) # 如果属性缺失超过所有缺失的20%就记录下来

缺失值的处理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# F1:将含有缺失值的记录删除
x <- algae
y <- na.omit()
y[!complete.case(y),]  # 可以发现没有缺失值了
x <- algae[-c(62,199),]  # 对于缺失值较多的情况,指定缺失值较多行来删掉
manyNAs(x)


# F2:根据变量之间相关关系填补缺失值
#首先要找数据间的相关关系
symnum(cor(algae[,4:18], use="complete.obs")) # 得到4-18字段之间的相关关系
x <- algae[-manyNAs(algae), ]
lm(PO4~oPO4)


# F3:根据案例之间相似性来填补
求距离值,把差值最小的依次排序,...

4.获取预测模型

获取预测模型

1
2
3
4
5
6
7
8
x <- algae[-manyNAs(algae), ]

clean.algae <- knnImputation(algae,k=10) # 通过元素相似性的方法处理了缺失值
clean.algae

# 第一个模型
lm.a1 <- lm(a1 ~., data=clean.algae[, 1:12]) # a1 ~. 代表a1和所有其他数据字段建立的相关关系
summary(lm.a1)

辅助变量

调整后的R的平方越接近1,就说明模型越科学

调整后的R的平方

5.预测模型的调优:

精简模型

1
2
3
anova(lm.a1)

# 如下图:说明season是对拟合误差的贡献是最小的,所以season对a1影响小,把a1去除

去除a1

1
2
3
4
5
6
7
8
9
# 去除a1
lm2.a1 <- update(lm.a1, . ~. -season)
# 发现Adjusted R-squared:  0.3259 已经变小了

# 对lm.a2进行分析,发现影响最小的是Chla字段,去掉Chla字段继续更新模型,不断重复来观察R平方的值是否越变越好
lm3.a1 <- update(lm1.a, . ~. -Chla)

# 来比较两个模型
anova(lm.a1, lm2.a1)

误差减小

为了简化上述不断重复来减小误差,R提供了一个更加简便的函数:step()

1
2
3
4
5
final.lm <- step(lm.a1) # 提升了模型预测精确度

summary(final.lm)

# 如果想要提高预测精度,也可以选用其他分析模型

得到140个水样,第一种海藻的频率

熟能生巧,以后多利用R来处理生活中的简单问题!

0%