美文网首页
《R語言初學者指南》學習筆記

《R語言初學者指南》學習筆記

作者: 余顺太 | 来源:发表于2020-06-18 10:55 被阅读0次

第一章 引言

#字体用consolas,Editor theme使用Merbivore;
?boxplot  #求助方法
help("boxplot")  #求助方法
q()  #会询问是否保存工作空间
q(save = "no")  #不会询问是否保存工作空间

#将R代码保存到文本编辑器中,不要保存到工作空间;若计算机需要花费很长时间才能去完成的时候可以通过File——Save Workspace进行保存,通过

getwd()  #获取当前工作目录
rm(list=ls(all=TRUE)) 或者 rm(list=ls()) #移除所有变量

#更改R版本:tools--global Options--General--R version-change--choose a specific version of R语言初学者指南

# ctrl + shift + c 一次性注释很多行,一次性取消很多注释也是如此
#R包安装:install.packages("plotrix");如果使用install.packages(plotrix)就无法安装成功
#小键盘上的0可以将R中的光标从竖直变为横着;

第二章 R 中的数据输入

Wingcrd<-c(59,55,53.5,55,52.5,57.5,53,55)  #c()函数生成了一个长度为8的向量
Wingcrd[1]  #查看第一个值
Wingcrd[1:5]  #查看前五个值
Wingcrd[-2]  #查看除第二个之外的值
sum(Wingcrd)  #求和
Tarsus<-c(22.3,19.7,20.8,20.3,20.8,21.5,20.6,21.5)
Head<-c(31.2,30.4,30.6,30.3,30.3,30.8,32.5,NA)
Wt<-c(9.5,13.8,14.8,15.2,15.5,15.6,15.6,15.7)
sum(Head)
sum(Head,na.rm = T) #na.rm 移除缺失值

#使用c,cbind,rbind结合变量
BirdData<-c(Wingcrd,Tarsus,Head,Wt)  #c结合变量会生成一个变量
BirdData
Z<-cbind(Wingcrd,Tarsus,Head,Wt)  #cbind结合的变量会以列的形式输出
Z
Z2<-rbind(Wingcrd,Tarsus,Head,Wt)  #rbind结合的变量会以行的形式输出
Z2

Id<-rep(c(1,2,3,4),each=8) 
Id

Id<-rep(1:4,each=8)
Id

a<-seq( from=1 , to = 4 , by=1 )
a
rep(a,each=8)

# ******Q1 ----------------------------------------------------------------------
#Q1: 如何产生 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4

VarName<-c("Wingcrd","Tarsus","Head","Wt")  #以字符形式结合

Id2<-rep(VarName,each=8)
Id2

Z<-cbind(Wingcrd,Tarsus,Head,Wt)  #cbind结合的变量会以列的形式输出,c表示column
Z

dim(Z)  #查看维度
dim(Z)[3]

使用矩阵结合数据

Dmat<-matrix(nrow = 8, ncol = 4)  #生成一个8X4的矩阵
Dmat
Dmat[,1]<-c(59,55,53.5,55,52.5,57.5,53,55)  #对矩阵进行数据填充
Dmat[,2]<-c(22.3,19.7,20.8,20.3,20.8,21.5,20.6,21.5)
Dmat[,3]<-c(31.2,30.4,30.6,30.3,30.3,30.8,32.5,NA)
Dmat[,4]<-c(9.5,13.8,14.8,15.2,15.5,15.6,15.6,15.7)
Dmat  #此时矩阵行和列还没有名字
colnames(Dmat)<-c("Wingcrd","Tarsus","Head","Wt")  #使用colnames函数给Dmat的列加上名字; 注意一点,就是这个函数放在了 <-的左边!
rownames(Dmat)<-c("甲","乙","丙","丁","戊","己","庚","辛")  #使用rownames函数给Dmat的行加上名字
Dmat

使用数据框(data.frame函数)结合数据

Dfrm<-data.frame(Wingcd=Wingcrd,Tarsus=Tarsus,Head=Head,Wt=Wt)  #
Dfrm

#cbind和matrix只能结合相同类型的数据,而data.frame可以结合不同类型的数据

使用list函数结合数据

#R中几乎所有的函数的输出结果都是保存在list中
x1 <- c(1,2,3)   #三个数字的向量
x2 <- c("a","b","c","d")   #三个字符的向量
x3 <- 3
x4 <- matrix(nrow = 2,ncol = 2)   #矩阵
x4[,1] <- c(1,2)  #给矩阵赋值
x4[,2] <- c(3,4)  #给矩阵赋值
x4
y <- list(x1=x1,x2=x2,x3=x3,x4=x4)  #用list将x1,x2,x3,x4这四个变量结合起来,若改为y <- list(x1,x2,x3,x4),则下一步的y$x2无法正常运行. =左边是自定义的名字,=右边是实质性内容;
y$x2
y
y[[1]] #取list的元素使用[[]]来实现
y[[2]]
y[[2]][1]

AllData <- list(BirdData=BirdData,Id=Id2,Z=Z,VarName=VarName)  # =左边是自定义的名字,=右边是实质性内容;
AllData
AllData$BirdData
AllData[[1]]
tmp<-AllData[[3]]
class(tmp)
AllData[[3]][1,] #因为AllData第三个元素Z是matrix,所以AllData[[3]][1,] 表示取该matrix的第一行
AllData[[3]][,1] #表示取该matrix的第一列

# list 和 data.frame 的差别?
# ******数据载入 -----------------------------------------------------------------
# read.table函数
# read.table读取的是txt文件

#可以使用绝对路径
Squid <- read.table(file = "D:/生信学习/猪年年尾R学习笔记/R语言初学者指南/乌贼数据.txt",header =T,dec=".")  #file =不写也可以;read.table读取的是txt文件!

#也可以先建立.Rproj后缀文件,然后打开该文件进行定位,然后打开Rstudio文件。注意:要在文件所在位置建立Rproj文件,但是要打开的Rstudio文件位置在哪里都可以,也就是说Rstudio文件并不需要和Rproj在同一个文件夹下。
Squid <- read.table(file = "乌贼数据.txt",header =T,dec=".") 
#header =T 有表头;dec=".",小数点字符为.
Squid
head(Squid)  #head函数看前几行
# 当一个目录下面有很多文件需要读取,可以先利用setwd函数设置一下工作路径,然后再read.table
setwd("D:/生信学习/猪年年尾R学习笔记/R语言初学者指南/")  #若上面使用了.Rproj进行了定位,则这里不可以更改路径。
Squid<-read.table(file="乌贼数据.txt",header = T)

# ******Answer of Q1 ---------------------------------------------------------
# 把each换成times就可以
Id<-rep(c(1,2,3,4),each=8) 
Id

Id<-rep(c(1,2,3,4), times=8) 
Id

第三章 访问变量和处理数据子集

#read.table函数应该和names以及str函数始终结合起来;因为这样可以查看变量,并且查看每个变量的属性;保证下一步不会出现错误;
setwd("D:/生信学习/猪年年尾R学习笔记/R语言初学者指南")
Squid<-read.table(file = "乌贼数据.txt",header = T,dec = ".")
Squid
names(Squid) #查看正在处理的变量
str(Squid) #查看数据框中每个变量的属性
head(Squid) #查看前几行
class(Squid)

Squid2<-read.table(file = "乌贼数据.txt",header = T,dec = ",") #我们如果将小数点错误的标为“,” 则GSI会被认为成一个因子(它不再是数值型变量),继续使用函数作图将会产生错误;
names(Squid2) #查看正在处理的变量
str(Squid2) #查看数据框中每个变量的属性。发现出了问题,GSI成为了因子。
class(Squid2)

访问数据框中的变量

方法一:$符号进行访问

Squid$GSI  #通过$符号访问数据框中的变量;
mean(Squid$GSI)  #计算均值

方法二:先attach,然后输入GSI

attach(Squid)  #使用attach命令将Squid添加到R的搜索路径里面
GSI  #避免每次输入Squid$
boxplot(GSI)
detach(Squid)  #用detach命令将Squid从R的搜索路径里面移除
GSI  #发现找不到

结合布尔运算符访问数据子集

unique(Squid$Sex)  #显示这个变量里面有多少个唯一值

访问所有性别为1的数据

Sel <- Squid$Sex ==1  #生成一个布尔向量用来选择行,若sex为1则该变量的值是TRUE,否则为FALSE
Sel
SquidM <- Squid[Sel,]  #选择Sel为TRUE的行; 注意选的是“行”,所以Sel放 = 前面
#以上两个步骤也可以合成一个步骤:SquidM <- Squid[Squid$Sex ==1,]
SquidM

访问数据Squid的Location为1,2,3的子集(即Location为1,2,3的行,所以后面要加逗号)

Squid123 <- Squid[Squid$Location ==1|Squid$Location ==2|Squid$Location ==3,] #|表示布尔运算符“或”
#以下三种也可以
# Squid123 <- Squid[Squid$Location !=4,] != 表示“不等于”
# Squid123 <- Squid[Squid$Location <=3,]
# Squid123 <- Squid[Squid$Location >=1 & Squid$Location <=3,]
Squid.1 <- Squid[Squid$Sex ==1 & Squid$Location ==1,] #需要满足Sex为1和Location为1两个条件,因为要提取符合条件的行,所以写在 = 前面
Squid.1
Squid.2 <- Squid[Squid$Sex ==1 & (Squid$Location ==1|Squid$Location ==2),] #需要满足Sex为1和Location为1或者2两个条件
Squid.2

数据排序(order)

Squid
Ord1 <- order(Squid$MONTH) #对月份进行排序
Ord1  
Squid[Ord1,]  #月份排序之后的Squid,为何要放在行上???因为要以排序后的月份对Squid每一行进行排列!
Squid$MONTH[Ord1] #月份排序之后的月份
Squid$Sample[Ord1]  #月份排序之后的Sample

数据集组合(merge)

setwd("D:/生信学习/猪年年尾R学习笔记/R语言初学者指南")
Sq1 <- read.table(file = "乌贼数据1.txt",header = T) #读取文件1
Sq2 <- read.table(file = "乌贼数据2.txt",header = T) #读取文件2
Sq1
Sq2
SquidMerged <- merge(Sq1, Sq2, by="Sample",all=T)  #使用变量Sample作为相同的标识符合并两个数据集,all=T表示如果有缺失值将用NA来填充;如果all=F则表示如果有缺失值将忽略;
#所谓的缺失值是指整行的缺失(这一点非常重要,意思是Sq1缺失了几个整行或者Sq2缺失了几个整行!)
SquidMerged

数据输出(write.table)

SquidM <- Squid[Squid$Sex ==1,]  #提取Sex为1的数据
write.table(SquidM,file = "MaleSquid.txt",sep = "",quote = F,append = F, na = "NA") #将上一步提取出来的数据输出到MaleSquid.txt里面
getwd()  #当前路径就是该文件所在路径
#通过write.table输出之后就可以发现多了一个文件,名为MaleSquid.txt。

重新编码分类变量(factor)

Squid
Squid$fLocation <- factor(Squid$Location, levels = c(1,2,3,4), labels = c("甲","乙","丙","丁")) #创建一个新的列,名字叫fLocation,它的内容就是将Location的1,2,3,4换为了甲乙丙丁
Squid$fLocation
Squid
Squid$fSex <- factor(Squid$Sex,levels = c(1,2),labels = c("M","F")) #创建一个新的列,名字叫fLocation,它的内容就是将Sex的1,2换为了M和F
Squid$fSex
Squid
boxplot(GSI ~ fSex, data =Squid) #把Squid的GSI和fSex分别拿出来,对应着进行boxplot画图;

第四章 简单的函数

setwd("c:/RBook/")
Veg <- read.table(file="Vegetation2.txt", header =TRUE)
Veg
head(Veg)
names(Veg)
str(Veg)

m <- mean(Veg$R)  #Veg$R表示将Veg中的R这一子集单独提取出来;mean(Veg$R)表示对Veg中R这一子集进行求取平均值;
m
m1 <- mean(Veg$R[Veg$Transect == 1])  #从外往里看,首先这是求平均值,求Veg中R这一子集的平均值,但不是求取所有R的平均值,有一个条件,就是被求取平均值的R要满足Transect为1, []之中为R要满足的条件。注意条件要用[ ]括起来;
m2 <- mean(Veg$R[Veg$Transect == 2])
m3 <- mean(Veg$R[Veg$Transect == 3])
m4 <- mean(Veg$R[Veg$Transect == 4])
m5 <- mean(Veg$R[Veg$Transect == 5])
m6 <- mean(Veg$R[Veg$Transect == 6])
m7 <- mean(Veg$R[Veg$Transect == 7])
m8 <- mean(Veg$R[Veg$Transect == 8])
c(m, m1, m2, m3, m4, m4, m5, m6, m7, m8)

tapply函数

tapply函数可以根据INDEX的不同水平对X进行FUN的运算;tapply(y,x,FUN=mean)

Veg$Transect
Me <- tapply(Veg$R, Veg$Transect, mean)  #等同于 Me <- tapply(X = Veg$R, INDEX = Veg$Transect ,FUN = mean)
Me
Sd <- tapply(Veg$R, Veg$Transect, sd)   #等同于 Sd <- tapply(X = Veg$R, INDEX = Veg$Transect, sd)
Sd
Le <- tapply(Veg$R, Veg$Transect, length) #等同于 Le <- tapply(X = Veg$R, INDEX = Veg$Transect, length)
Le
cbind(Me, Sd, Le)

sapply函数

sapply函数对y的每一个变量使用FUN的函数;sapply(y,FUN=mean)

Me <- mean(Veg$R) #求整个序列的均值
Mi <- min(Veg$R)  #求整个序列的最小值
Ma <- max(Veg$R)  #求整个序列的最大值
Sd <- sd(Veg$R)  #求整个序列的标准差
Le <- length(Veg$R)  #求整个序列的长度
c(Me,Mi,Ma,Sd,Le)
names(Veg)  #通过names函数我们可以发现有很多变量
length(Veg)  #通过length函数我们发现有24个变量,如果我们想对每一个变量都求平均值,就需要使用mean()函数24次
#sapply函数可以避免以上囧状

sapply(Veg[, 5:10], FUN = mean)  #对Veg的5到10列求取mean值
sapply(Veg[, 5:10], function(x) {mean(x)})  #与上面等价

lapply(Veg[, 5:10], FUN = mean)  #lapply和sapply函数一样功能,只不过输出结果形式不一样;sapply函数的输出是一个向量,lapply函数的输出是一个列表;
lapply(Veg[, 5:10], function(x) {mean(x)})

总结:tapply函数计算的是一个变量观察值子集的均值(或其他函数);
lapply和sapply函数计算的是一个或多个变量全部观察值的均值(或其他函数);
lapply和sapply中包含数据的变量必须是数据框

summary函数

summary函数可以提供变量基本信息

Z <-cbind(Veg$R, Veg$ROCK, Veg$LITTER, Veg$ML)  #使用cbind将几个变量结合起来
Z
head(Z)
colnames(Z) <- c("R","ROCK","LITTER","ML")  #如果没有这一步输出的结果每一列会没有名字,这一步的作用是给每一列添加名字!
head(Z)
summary(Z) #提供变量信息
names(Veg)

summary(Veg[,c("R","ROCK","LITTER","ML")])  #可以实现同样的功能
summary(Veg[,c(5,6,7,8)])  #可以实现同样的功能

setwd("D:/生信学习/猪年年尾R学习笔记/R语言初学者指南/RBook")
Deer <- read.table(file="Deer.txt")
names(Deer)
str(Deer)

table(Deer$Farm)
table(Deer$Sex, Deer$Year)

第五章 基础绘图工具简介

setwd("c:/RBook/")
Veg <- read.table(file="Vegetation2.txt",header =TRUE)
plot(Veg$BARESOIL, Veg$R, xlab = "BARESOIL", ylab = "R")  #注意自变量和因变量,也可以 plot(x = Veg$BARESOIL, y = Veg$R, xlab = "BARESOIL", ylab = "R")来指定自变量和因变量
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=16)  #xlim和ylim设定取值范围,pch是指定绘图字符;
?plot  #可以查看很多参数

不同时间使用不同符号来表示

unique(Veg$Time)  #查看总共有几个年份
Veg$Time2 <- Veg$Time  #将这些年份生成一个对于pch有效的新的数值向量
Veg$Time2[Veg$Time == 1958] <-1 #[]里面是条件,此处也可以改为Veg$Time2[Veg$Time2 == 1958] <-1,因为在<-左边Time和Time2是对应起来的,<-右边才是条件判断过之后进行的赋值;
Veg$Time2[Veg$Time == 1962] <-2
Veg$Time2[Veg$Time == 1967] <-3
Veg$Time2[Veg$Time == 1974] <-4
Veg$Time2[Veg$Time == 1981] <-5
Veg$Time2[Veg$Time == 1994] <-6
Veg$Time2[Veg$Time == 2002] <-7
Veg$Time2[Veg$Time == 1989] <-8
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time2)  #我们将不同年份的数据使用不同的符号进行了标示!

#也可以如下操作
Veg$Time3 <- Veg$Time
Veg$Time3
Veg$Time3[Veg$Time <= 1974] <- 1  ##[]里面是条件,此处也可以改为Veg$Time3[Veg$Time3 <= 1974] <- 1,因为在<-左边Time和Time3是对应起来的,<-右边才是条件判断过之后进行的赋值;
Veg$Time3[Veg$Time > 1974] <- 16
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time3)

改变绘图符号颜色

#在plot函数里面对col选项使用向量
Veg$Time3 <- Veg$Time
Veg$Time3
Veg$Time3[Veg$Time <= 1974] <- 1  ##[]里面是条件,此处也可以改为Veg$Time3[Veg$Time3 <= 1974] <- 1,因为在<-左边Time和Time3是对应起来的,<-右边才是条件判断过之后进行的赋值;
Veg$Time3[Veg$Time > 1974] <- 16

Veg$col3[Veg$Time <= 1974] <- 1  #生成颜色向量1
Veg$col3[Veg$Time > 1974] <- 2   #生成颜色向量2
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time3, col=Veg$col3)

改变绘图符号尺寸

# 使用cex选项改变尺寸
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time3, col=Veg$col3, cex=5)

#也可以对cex使用向量,即对不同年份使用不同尺寸来表示
Veg$cex2 <- Veg$Time
unique(Veg$Time)
Veg$cex2[Veg$Time <= 1974] <- 1.5
Veg$cex2[Veg$Time > 1974] <- 4
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time3, col=Veg$col3, cex=Veg$cex2)

添加一条平滑线

plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标",
     xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time3, col=Veg$col3, cex=Veg$cex2)
##不进行排序直接拟合会画出多条线
M.Loess <- loess(R ~ BARESOIL, data = Veg)  #R ~ BARESOIL表示R可以作为BARESOIL的函数
Fit <- fitted(M.Loess)  #提取拟合值并将其赋值给Fit
lines(Veg$BARESOIL, Fit)  #第一个参数绘制横坐标,第二个参数绘制纵坐标,画线,但是发现是多条线,因为line命令的第一个参数是按照表里面顺序连接点的

#所以我们要先进行排序,然后才可以进行线的拟合
plot(x = Veg$BARESOIL, y = Veg$R, xlab = "横坐标", ylab = "纵坐标", xlim = c(0,50), ylim =c(0,20),main="标题", pch=Veg$Time3, col=Veg$col3, cex=Veg$cex2)
M.Loess <- loess(R ~ BARESOIL, data = Veg)  #R ~ BARESOIL表示R可以作为BARESOIL的函数
Fit <- fitted(M.Loess)  #提取拟合值并将其赋值给Fit
Ord1 <- order(Veg$BARESOIL)
lines(Veg$BARESOIL[Ord1], Fit[Ord1], lwd = 5, lty = 2, col="black")  #lwd表示线的宽度,lty表示线的类型,col可以用“颜色单词”表示,也可以直接用数字表示!

第六章 循环与函数

补充一个知识点

sort、order函数的分别

sort()函数是对向量进行从小到大的排序
order()函数返回的值表示位置

举个例子

a <- c(6, 8, 2, 5)
sort(a)
order(a) #order()函数返回的值表示位置,返回值是3,4,1,2表示第三个数排在第一位,第四个数排在第二位,第一个数排在第三位,第二个数排在第四位。


setwd("C:/RBook/")
Owls <- read.table(file="Owls.txt",header = TRUE)
names(Owls)
str(Owls)
head(Owls)
dim(Owls)
unique(Owls$Nest)

#想要探索Owls文件中每一个Nest子集里面Arrival Time和Negotiation behaviour的关系
#例子1:探索Owls文件中第一个Nest子集(AutavauxTV)里面Arrival Time和Negotiation behaviour的关系
Owls.ATV<-Owls[Owls$Nest=="AutavauxTV",]  #提取子集!这个非常的好理解,可以打开Owls.txt对应着看一下;[]里面是条件,Owls$Nest表示文件中的第一列,
# 但是通过unique(Owls$Nest)函数也可以发现第一列有好几个不同的行,所以=="AutavauxTV",表示要名字为AutavauxTV的这几行!
plot(x = Owls.ATV$ArrivalTime, y = Owls.ATV$NegPerChick,
     xlab = "Arrival Time", ylab = "Negotiation behaviour",
     main =  "AutavauxTV", cex=1.2, col = "red", pch = 16)

#例子2:探索Owls文件中第二个Nest子集(Bochet)里面Arrival Time和Negotiation behaviour的关系
Owls.Bot <- Owls[Owls$Nest=="Bochet",]  #提取Bochest子集
plot(x = Owls.Bot$ArrivalTime, y = Owls.Bot$NegPerChick,
     xlab = "Arrival Time", ylab = "Negotiation behaviour",
     main =  "Bochet", cex=1.2, col = "black", pch = 16)

#例子3:探索Owls文件中第三个Nest子集(Champmartin)里面Arrival Time和Negotiation behaviour的关系
Owls.Cha <- Owls[Owls$Nest=="Champmartin",]  #提取Bochest子集
plot(x = Owls.Cha$ArrivalTime, y = Owls.Cha$NegPerChick,
     xlab = "Arrival Time", ylab = "Negotiation behaviour",
     main =  "Champmartin", cex=1.2, col = "purple", pch = 16)
#                              .
#                              .
#                              .
#                              
#                 这样下去需要重复25遍才能结束!

# Nest.i <- "子集名称"
# Owls.i <- Owls[Owls$Nest==Nest.i,]
# plot(x = Owls.i$ArrivalTime, y = Owls.i$NegPerChick,
#      xlab = "Arrival Time", ylab = "Negotiation behaviour",
#      main =  Nest.i, cex=1.2, col = "purple", pch = 16)

图像的保存

#将上面的第一个保存下来
setwd("D:/生信学习/猪年年尾R学习笔记/R语言初学者指南/AllGraphs")  #设定好图片保存的路径, 有时候会报错,重新将地址复制过来就好了。
jpeg(filename = "AutavauxTV.jpg")  #打开画布,需要先打开画布,然后再plot才可以!
Owls.ATV<-Owls[Owls$Nest=="AutavauxTV",]  #提取子集
plot(x = Owls.ATV$ArrivalTime, y = Owls.ATV$NegPerChick,
     xlab = "Arrival Time", ylab = "Negotiation behaviour",
     main =  "AutavauxTV", cex=1.2, col = "red", pch = 16)  #作图
dev.off()  #关闭画布,不关闭则无法打开图片

构造循环

AllNests <- unique(Owls$Nest)  #使用unique确定Nest名字唯一性;
for (i in 1:27){
  Nest.i <- AllNests[i]  #使Nest.i 和第i个Nest名字对应起来
  Owls.i <- Owls[Owls$Nest == Nest.i,]  #提取第i个子集
  YourFileName <- paste(Nest.i,".jpg",sep="")  #paste可以将变量连接为字符串;使用paste函数对每一个图片的进行命名,可以分别改变一下里面参数,看一下什么变化。
  jpeg(file=YourFileName)  #打开画布,这一步要在plot之前
  plot(x = Owls.i$ArrivalTime, y = Owls.i$NegPerChick,
       xlab = "Arrival Time", ylab = "Negotiation time",
       main =  Nest.i, pch=16)  #画图
  dev.off()  #关闭画布
}

函数

对每一个变量制作一个表格给出缺失值和零的个数

例子1:确定每个变量中缺失值的数量

setwd("C:/RBook")
Veg <- read.table(file = "Vegetation2.txt", header = T)
names(Veg)
str(Veg)
head(Veg)

NAPerVariable <- function(X1){  #function构造一个函数,函数名字是 NAPerVariable
  D1 <- is.na(X1)  #这里进行一个判断; is.na(X1)生成一个与X1维数相同的布尔矩阵,并将X1矩阵中的缺失值计为TRUE,非缺失值计为FALSE;
  colSums(D1)  #计算每一列元素的和;colSums是R中已有的函数,colsum函数的对象通常为数值矩阵,也可以是布尔矩阵,它会将布尔矩阵中的TRUE计为1,FALSE计为0;并且变量的任何位置出现了空值则colSum函数的输出就为空值,可以通过设定na.rm = TRUE来实现;
}

#X1和D1的解释
# X1是NAPerVariable这个函数的变量,把什么变量给NAPerVariable函数,则X1就是什么
# D1是通过is.na(X1)生成的与X1维数相同的布尔矩阵,并将X1矩阵中的缺失值计为TRUE,非缺失值计为FALSE;

NAPerVariable(Veg[,1:24]) #因为NAPerVariable是刚刚写好的函数,所以直接拿来用,在这里X1就是Veg[,1:24]

例子2:确定每个变量中缺失值的数量

setwd("c:/RBook/")
Parasite <- read.table(file="CodParasite.txt", header = TRUE)
names(Parasite)
str(Parasite)

NAPerVariable<-function(X1) {
  D <- is.na(X1)
  colSums(D)
}

NAPerVariable(Parasite) #在这里X1就是Parasite

例子3:确定每个变量中零值的数量

ZerosPerVariable<-function(X1) {
  D1 =(X1 == 0)  #在这里进行判断,等于0就是TRUE,否则就是FALSE;这个括号有没有都可以的;
  colSums(D1, na.rm = T)  #通过设定na.rm = TRUE来移除缺失值
}

ZerosPerVariable(Parasite) #在这里X1就是Parasite

例子4:同时确定每个变量中缺失值和零值的数量

VariableInfo<-function(X1,Choice1) {  #在这里Choice1是一个有两种选择的变量。
  if (Choice1 =="Zeros"){ D1 = X1 == 0 }
  if (Choice1 =="NAs")  { D1 <- is.na(X1)}
  colSums(D1, na.rm = TRUE)
}
#函数 VariableInfo 有两个参数:X1 和 Choice1。X1是数据框,Choice1是一个有两种选择的变量。

VariableInfo(Parasite,"Zeros")  #在这里函数 VariableInfo的两个参数:X1 和 Choice1分别对应着 Parasite 和 "Zeros"
VariableInfo(Parasite,"NAs")
VariableInfo(Parasite,"error test") #因为Choice1只有两种可能性的选择,"Zeros"或者"NAs","error test"不符合两种选择中的任何一个,所以会显示error

例子5:同时确定每个变量中缺失值和零值的数量,并且当输入错误时可以显示特定的提示信息

VariableInfo<-function(X1,Choice1 = "Zeros") {  #这里写的Choice1 = "Zeros"而不仅仅写的Choice1,就相当于设置了默认值为Choice1 = "Zeros"
  if (Choice1 =="Zeros"){ D1 <- X1 == 0 }
  if (Choice1 =="NAs")  { D1 <- is.na(X1)}
  if (Choice1 != "Zeros" & Choice1 != "NAs") {print("What the fuck! You made a typo! You're so stupid!!!")} else {
    colSums(D1, na.rm = TRUE)}
}

VariableInfo(Parasite)  #因为默认值是Choice1 = "Zeros",所以这里不给choice1的值会按Choice1 = "Zeros"来进行计算。
VariableInfo(Parasite,"Zeros")
VariableInfo(Parasite,"NAs")
VariableInfo(Parasite,"error test")  #若输入错误则会有特定的提示信息!

例子6:对例子5进行简化,使if数量达到最少

VariableInfo<-function(X1, Choice1 = "Zeros") {
  ifelse (Choice1 =="Zeros", D1 <- (X1 == 0) , D1 <- is.na(X1))  # ifelse替代了前面两个if命令
  if (Choice1 != "Zeros" & Choice1 != "NAs") {print("What the fuck! You made a typo! You're so stupid!!!")} else {
    colSums(D1, na.rm = TRUE)}}

VariableInfo(Parasite)
VariableInfo(Parasite,"NAs")
VariableInfo(Parasite,"Zeros")
VariableInfo(Parasite,"error test")  #若输入错误则会有特定的提示信息!


setwd("C:/RBook/")
Benthic <- read.table("RIKZ.txt",header=T)
Species <- Benthic[,2:76]
n <- dim(Species)
n
sum(Species[1, ], na.rm = TRUE)
sum(Species[2, ], na.rm = TRUE)
sum(Species[3, ], na.rm = TRUE)
sum(Species[4, ], na.rm = TRUE)
#        .
#        .
#        .
# 构造循环来避免该命令写45遍
TA <- vector(length = n[1])  #构造了一个长度为45的空向量
TA  #此时里面45个位置都是空的
for (i in 1:n[1]){
  TA[i] <- sum(Species[i,], na.rm = TRUE)
}

TA

# 其实有更简洁的方式
TA <- rowSums(Species, na.rm = T)  # rowSums函数计算每一行的和
TA  

统计每一行的数值大于0的个数

dim(Species) #总共45行75列
sum(Species[1, ] > 0, na.rm = TRUE)  #Species[1, ] > 0是一个判断式,起到了判断的作用,对Species第一行的75个值进行判断,若该值大于0则为TRUE,返回1,否则为FALSE返回0。然后sum进行了求和,得到的值就是TRUE的个数,即第一行75个数值中满足 >0 这一条件的个数。
sum(Species[2, ] > 0, na.rm = TRUE)
sum(Species[3, ] > 0, na.rm = TRUE)
sum(Species[4, ] > 0, na.rm = TRUE)
#        .
#        .
#        .
# 构造循环来避免该命令写45遍

Richness <- vector(length = n[1]) #构造了一个长度为45的空向量
Richness  #此时里面45个位置都是空的
for (i in 1:n[1]){
  Richness[i] <- sum(Species[i, ] > 0, na.rm = TRUE)
}  #for循环对这45个空位置进行一一填充
Richness

# 其实有更简洁的方式
Richness <- rowSums(Species > 0, na.rm = TRUE) # Species > 0对每一行数据进行判断,若判断成立则返回TRUE,值为1,否则返回FALSE值为0,rowSums函数在这里计算的结果就是满足条件的值的个数。
Richness

RS <- rowSums(Species, na.rm = TRUE)  #因为这里不是判断式,所计算的是每一行的和
RS

prop <- Species / RS
prop
H <- -rowSums(prop * log10(prop), na.rm = TRUE)
H

suppressMessages(install.packages("vegan"))
library(vegan)
H <- diversity(Species)
H

Choice <- "Richness"

if (Choice == "Richness") {
  Index <- rowSums(Species >0 , na.rm = TRUE)}
if (Choice == "Total Abundance") {
  Index <- rowSums(Species, na.rm = TRUE) }
if (Choice=="Shannon") {
  RS <- rowSums(Species, na.rm = TRUE)
  prop <- Species / RS
  Index <- -rowSums(prop * log10(prop), na.rm = TRUE)}


Index.function <- function(Spec, Choice){
  if (Choice == "Richness") {
    Index <- rowSums(Spec>0, na.rm = TRUE)}
  if (Choice == "Total Abundance") {
    Index <- rowSums(Spec, na.rm = TRUE) }
  if (Choice=="Shannon") {
    RS <- rowSums(Species, na.rm = TRUE)
    prop <- Species / RS
    Index <- -rowSums(prop * log10(prop), na.rm = TRUE)}
  list(Index = Index, MyChoice = Choice)
}

第七章 图形工具

setwd("C:/RBook/")
BFCases <- read.table(file="BirdFluCases.txt", header = TRUE,sep="\t")
names(BFCases)
dim(BFCases)
str(BFCases)
head(BFCases)
Cases <- rowSums(BFCases[,2:16])  # rowSum对每一行进行求和计算;对BFCases的2到16列的每一行求和!
Cases  #此时还没有名字
names(Cases) <- BFCases[,1]  # names函数将BFCases的第一列内容赋给了Cases,作为Cases的名字;
Cases  #此时有了名字
head(BFCases)

pie函数画饼图

Piechart

par(mfrow = c(2,2), mar = c(3, 3, 2, 1)) #mfrow是指面板能生成的图形个数与排版;mar是指每个图形周围空间大小;(改一下参数试下就明白了!)
pie(Cases , main = "Ordinary pie chart")
pie(Cases , col = gray(seq(0.4,1.0,length=6)), clockwise=T, main = "Grey colours")  #clockwise=T是指显示的方向
pie(Cases , col = rainbow(6), clockwise = TRUE, main="Rainbow colours")

3D Exploded Pie Chart

library(plotrix)
pie3D(Cases , labels = names(Cases), explode = 0.1, main = "3D pie chart", labelcex=0.6)

par函数对画布进行设置

op <- par(mfrow = c(2,2), mar = c(3, 3, 2, 1))  # mfrow是指面板能生成的图形个数与排版;mar是指每个图形周围空间大小;(改一下参数试下就明白了!)
pie(Cases , main = "Ordinary pie chart")
pie(Cases , col = gray(seq(0.4,1.0,length=6)), clockwise=TRUE, main = "Grey colours")
pie(Cases , col = rainbow(6),clockwise = TRUE, main = "Rainbow colours")
pie3D(Cases , labels = names(Cases ), explode = 0.1, main = "3D pie chart", labelcex=0.6)
par(op)  #图行参数设置保存在了第一行代码的op里面,这里再进行一下par(op)表示结束par设置,就像par从来没有使用过一样。

绘制条形图

BFDeaths <- read.table(file="BirdFluDeaths.txt", header = TRUE, sep="\t")
Deaths <- rowSums(BFDeaths[,2:16]) #rowSum对每一行进行求和计算;对BFDeaths的2到16列的每一行求和!
Deaths #还没有名字
names(Deaths) <- BFDeaths[,1]  #names函数将BFCases的第一列内容赋给了Cases,作为Cases的名字;
Deaths #有名字了

Counts <- cbind(Cases, Deaths)  #以列的形式结合向量;
Counts

par(mfrow = c(2,2), mar = c(3, 3, 2, 1))  #par函数进行画布设置
barplot(Cases , main = "Bird flu cases")
barplot(Counts)
barplot(t(Counts), col = gray(c(0.5,1))) #gray(c(0.5,1)))是指两个灰度
barplot(t(Counts), beside = TRUE)  #beside是指两个是上下形式还是左右形式;上面那个默认为F
# t函数将数据进行了转置,如果不转置则是分成了Cases和Deaths两组,经过转置之后以年份分为了6组

在条形图上显示均值和标准差以及外部线框

setwd("C:/RBook/")
Benthic <- read.table(file = "RIKZ2.txt", header = TRUE, sep="\t")
dim(Benthic)
head(Benthic)

Bent.M <- tapply(Benthic$Richness, INDEX=Benthic$Beach, FUN=mean)  #Benthic$Richness表示Benthic文件中Richness这一元素!
head(Bent.M)
Bent.sd <- tapply(Benthic$Richness, INDEX=Benthic$Beach, FUN=sd)
head(Bent.sd)
MSD<- cbind(Bent.M, Bent.sd)
MSD

bp <- barplot(Bent.M, xlab = "Beach", ylab = "Richness", col = rainbow(9), ylim = c(0,20))
bp  # bp表示沿x轴每个条形图的中点。
arrows(bp, Bent.M, bp, Bent.M + Bent.sd, lwd = 1.5, angle=90,length=0.1) 
# arrows给图形加标准差垂直线。 bp, Bent.M表示标准差垂直线的起点;bp, Bent.M + Bent.sd表示标准差垂直线的终点,lwd是线宽,angle=90,length=0.1表示标准差垂直线的顶端线与标准差垂直线的角度和顶端线的长度。
box()  #给图形加一个线框框住

Benth.le <- tapply(Benthic$Richness, INDEX=Benthic$Beach, FUN=length)
Bent.se <- Bent.sd / sqrt(Benth.le)  #计算标准误

stripchart(Benthic$Richness ~ Benthic$Beach, vert = TRUE, pch=1, method = "jitter", jit = 0.05, xlab = "Beach", ylab = "Richness")
points(1:9, Bent.M, pch = 16, cex = 1.5)  #在均值上加点

arrows(1:9, Bent.M, 1:9, Bent.M + Bent.se, lwd = 1.5, angle=90, length=0.1)  #加号表示正的se
arrows(1:9, Bent.M, 1:9, Bent.M - Bent.se, lwd = 1.5, angle=90, length=0.1)  #减号表示负的se

Add lines for sd.

boxplots

setwd("C:/RBook/")
Owls <- read.table(file = "Owls.txt", header= TRUE, sep="\t")
boxplot(Owls$NegPerChick, main = "Negotiation per chick")
par(mfrow = c(2,2), mar = c(3, 3, 2, 1))  #布置画布
head(Owls)
Owls$LogNeg <- log10(Owls$NegPerChick + 1)  #新加了一列名为LogNeg ,把Owls文件中NegPerChick这一子集提取出来,做相应的运算,赋值给左边.
head(Owls)
boxplot(NegPerChick~SexParent, data = Owls)  #把NegPerChick的数据按照SexParent进行画图
boxplot(NegPerChick~FoodTreatment, data = Owls)  #把NegPerChick的数据按照FoodTreatment进行画图
boxplot(NegPerChick~SexParent * FoodTreatment,data = Owls)  #把NegPerChick的数据按照SexParent 和 FoodTreatment进行画图
boxplot(NegPerChick~SexParent * FoodTreatment, names = c("F/Dep","M/Dep","F/Sat","M/Dep"),data = Owls)#把NegPerChick的数据按照SexParent 和 FoodTreatment进行画图,并进行命名;

在条形图上加标签

par(mar = c(2,2,3,3))
boxplot(NegPerChick~Nest, data = Owls, axes = FALSE, ylim = c (-3.5, 9))   #axes表示轴线
axis(2, at = c(0, 2, 4, 6, 8))  #1表示行,2表示列,在图片左边生成一个轴,axis的第一个参数是位置;at参数指的是要标记的刻度;
text(x = 1:27, y = -2, labels = levels(Owls$Nest),cex=0.75, srt=60)     # y=-2表示该标签在y轴的相对位置,放置标签,cex表示字体大小,srt表示倾斜角度!
levels(Owls$Nest)
    

#Boxplot for RIKZ data
setwd("C:/RBook/")
Benthic <- read.table(file = "RIKZ2.txt", header= TRUE, sep="\t")
head(Benthic)
names(Benthic)
Bentic.n <- tapply(Benthic$Richness, Benthic$Beach, FUN =length) #对文件Benthic,以Beach对Richness进行分组,统计每组数据个数
Bentic.n
bp <- boxplot(Richness ~ Beach, data = Benthic, col = "grey",  
              xlab = "Beach", ylab = "Richness")  #boxplot函数可以将信息存储在一个list里面,也就是此处的bp包含好几个变量!
bp
str(bp)

bpmid <- bp$stats[2, ] + (bp$stats[4,] - bp$stats[2,]) / 2
bpmid
text(1:9, bpmid, Bentic.n, col = "white", font = 2)  #x=1:9是向量的长度,y=bpmid表示9元素向量的位置,labels =Bentic.n表示9元素向量的内容
?text

心得!
对于一个函数没有必要去背,比如这里text(1:9, bpmid, Bentic.n, col = "white", font = 2) 是什么意思就很难背下来每一个参数对应哪一个,只要?text一下就可以很容易的对应上

text(x, y = NULL, labels = seq_along(x$x), adj = NULL,
      pos = NULL, offset = 0.5, vfont = NULL,
      cex = 1, col = NULL, font = NULL, ...)  #只要一对应就好了,知道1:9, bpmid, Bentic.n,分别对应着x,y,labels,然后再在帮助文档看一下什么意思就可以了。

点图

很重要的一点,这个点图上下的摆动是随机分布的(这种随机是指限制在组内的随机),但是左右的摆动是按照他的刻度来的!

?dotchart
setwd("C:/RBook/")
Deer <-read.table("Deer.txt", header = TRUE, sep="\t")
par(mfrow=c(1,2))  #布置画布
dotchart(Deer$LCT, xlab="Length (cm)", ylab = "Observation number")

dotchart(Deer$LCT, groups = factor(Deer$clas1_4))  #groups选项允许数据根据分类变量进行分组!因为Sex变量里面有缺失值,所以这一条命令执行不成功。
Deer$clas1_4
Isna <- is.na(Deer$clas1_4)  #is.na是检测缺失值的函数,若返回值为TRUE则为缺失值,FALSE则为非缺失值;
!Isna  #符号!将Isna进行了一个颠倒。颠倒了之后下一步的作图只会去对TRUE的进行绘图。

dotchart(Deer$LCT[!Isna], groups = factor(Deer$clas1_4[!Isna]), 
         xlab = "Length (cm)", ylab = "Observation number grouped by sex")  


setwd("C:/RBook/")
Benthic <- read.table(file = "RIKZ2.txt", header= TRUE,sep="\t")
head(Benthic)
sum(Benthic$Beach)  #因为Benthic$Beach是数值型向量,所以可以求和;

Benthic$fBeach <- factor(Benthic$Beach)  #factor将数值型向量变为了因子。可以通过sum函数发现Benthic$Beach可以求和,Benthic$fBeach却不可以;
sum(Benthic$fBeach)  #因为Benthic$Beach是因子,所以不能求和;
par(mfrow=c(1,2))
dotchart(Benthic$Richness,groups=Benthic$fBeach,  #如果省略掉Benthic$fBeach <- factor(Benthic$Beach) 这一步,则groups=Benthic$fBeach就应该写成groups=factor(Benthic$Beach)
         xlab="Richness", ylab = "Beach")

Bent.M<-tapply(Benthic$Richness,Benthic$Beach,FUN = mean)
Bent.M

dotchart(Benthic$Richness,groups=Benthic$fBeach,
         gdata = Bent.M, gpch=19, xlab="Richness", ylab="Beach")  # gdata用来表示一个值,这里指的平均值

legend("bottomright",c("values","mean"),pch=c(1,19),bg="red")  #legend函数添加图例,bg表示背景色的颜色

plot函数

setwd("C:/RBook/")
Benthic <- read.table(file = "RIKZ2.txt", header= TRUE,sep="\t")
Benthic$fBeach <- factor(Benthic$Beach)
plot(Benthic$Richness,Benthic$fBeach)
par(mfrow = c(2,2), mar = c(4,4,2,2) +.5)

plot(y = Benthic$Richness, x = Benthic$NAP,
     xlab = "Mean high tide (m)", ylab = "Species richness",
     main = "Benthic data")

M0 <- lm(Richness ~ NAP, data = Benthic)  #lm利用线性回归建立模型,结果存储在列表M0里面
abline(M0)  #abline函数添加拟合线

plot函数中type,axes函数选项

plot(y = Benthic$Richness, x = Benthic$NAP,
     type = "n", axes = FALSE,  #type表示图形的类型,n就表示不画图;axes表示轴线
     xlab = "Mean high tide", ylab = "Species richness")
?plot  #可以看到,如果将type = "n"换成type = "p"就会出图;

     xlab = "Mean high tide", ylab = "Species richness")
points(y = Benthic$Richness, x = Benthic$NAP)

plot(y = Benthic$Richness, x = Benthic$NAP,
     type = "n", axes = FALSE,
     xlab = "Mean high tide", ylab = "Species richness",
     xlim = c(-1.75,2), ylim = c(0,20))
points(y = Benthic$Richness, x = Benthic$NAP)

axis命令绘制轴线

axis(2, at = c(0, 10, 20), tcl = 1)  #axis第一个参数2表示在左边添加轴,at表示添加的刻度;tcl表示z轴上刻度的长短;
axis(1, at = c(-1.75,0,2), labels = c("Sea","Water line","Dunes") )

点/文本/线的添加

setwd("C:/RBook/")
Birds <- read.table(file="loyn.txt", header= TRUE, sep="\t")
Birds$LOGAREA<- log10(Birds$AREA)
Birds$fGRAZE <- factor(Birds$GRAZE)

M0 <- lm(ABUND~ LOGAREA + fGRAZE, data = Birds)
summary(M0)

plot(x = Birds$LOGAREA, y = Birds$ABUND, xlab="Log transformed AREA", ylab="Bird abundance")

改变字体和字体大小

windowsFonts()  #查看目前已经安装好的字体类型
title("Fitted model", cex.main = 2, family = "sans", font.main = 1)  #family指字体类型,font.main指字体大小

#计算五个拟合值
LAR<-seq(-1, 3, by = 0.1)

ABUND1 <- 15.7 +  7.2 * LAR
ABUND2 <- 16.1 +  7.2 * LAR
ABUND3 <- 15.5 +  7.2 * LAR
ABUND4 <- 14.1 +  7.2 * LAR
ABUND5 <- 3.8 +  7.2 * LAR

#把拟合值作为线添加到图形上
lines(LAR, ABUND1, lty = 1, lwd = 1, col =1)
lines(LAR, ABUND2, lty = 2, lwd = 2, col =2)
lines(LAR, ABUND3, lty = 3, lwd = 3, col =3)
lines(LAR, ABUND4, lty = 4, lwd = 4, col =4)
lines(LAR, ABUND5, lty = 5, lwd = 5, col =5)

legend.txt <- c("Graze 1","Graze 2","Graze 3","Graze 4","Graze 5")

图例添加

legend("topleft",  #topleft表示位置
       legend = legend.txt,  #要标注的内容
       col = c(1,2,3,4,5),  #拟合线的颜色
       lty = c(1,1,1,1,5),  #图例线的形式,lty=1表示实心;
       lwd = c(1,2,3,4,5),  #图例线条的粗细
       bty = "o",  #添加围绕图例的盒子
       cex = 0.8  #图例文本大小
)

添加特殊符号

setwd("C:/RBook/")
Whales <- read.table(file="TeethNitrogen.txt", header= TRUE)
head(Whales)

N.Moby1 <- Whales$X15N[Whales$Tooth == "Moby"]  #因为[,]的逗号左边是行,右边是列;但是要求被取值的内容不能是一维度,否则哪里来的行和列?因为此处Whales$X15N是一维数据,所以[]中不能加逗号;
N.Moby1

#N.Moby2 <- Whales[Whales$Tooth == "Moby",]  #因为[,]的逗号左边是行,右边是列;但是要求被取值的内容不能是一维度,否则哪里来的行和列?
#N.Moby2

强烈注意:

关于[]取子集什么时候加逗号,什么时候不加逗号

因为逗号是用来分隔行和列的,逗号前的为行,逗号后的为列;所有加逗号取子集的前提是被取值的内容不是一维数据,有行有列是二维啊;所以,一维数据取子集不用加逗号,因为一维没有行列;

Age.Moby <- Whales$Age[Whales$Tooth == "Moby"]
plot(x = Age.Moby, y = N.Moby, xlab = "Age", ylab = expression(paste(delta^{15}, "N")))

pairs 函数生成多面板的散点图

setwd("C:/RBook/")
Benthic <- read.table(file = "RIKZ2.txt", header= TRUE)
head(Benthic)
class(Benthic)
pairs(Benthic[, 2:9])  #等同于plot(Benthic[,2:9]),因为Benthic是一个数据框,plot函数能够识别它并能调用函数plot.data.frame
#生成的图片对角线显示的是变量的名称,表示对角线上方或下方面板的x轴变量名称,同时还表示对角线左方或右方面板y轴的变量名称
#即每一个图片都可以画一个横轴,也可以画一个纵轴,会跟对角线有交点,交点就是x变量和y变量
#这种多组图有一半的图是多余的,因为每幅图都会出现两次;分别出现在对角线上下方,但坐标轴是颠倒的。

pairs(Benthic[, 2:9], diag.panel = panel.hist, upper.panel = panel.smooth, lower.panel = panel.cor)



# 皮尔逊相关系数应用于pairs函数 -------------------------------------------------
panel.hist <- function(x, ...)
{
  usr <- par("usr"); on.exit(par(usr))
  par(usr = c(usr[1:2], 0, 1.5) )
  h <- hist(x, plot = FALSE)
  breaks <- h$breaks; nB <- length(breaks)
  y <- h$counts; y <- y/max(y)
  rect(breaks[-nB], 0, breaks[-1], y, col="cyan", ...)
}


panel.cor <- function(x, y, digits=2, prefix="", cex.cor)
{
  usr <- par("usr"); on.exit(par(usr))
  par(usr = c(0, 1, 0, 1))
  r <- abs(cor(x, y))
  txt <- format(c(r, 0.123456789), digits=digits)[1]
  txt <- paste(prefix, txt, sep="")
  if(missing(cex.cor)) cex <- 0.8/strwidth(txt)
  text(0.5, 0.5, txt, cex = cex * r)
}

pairs(Benthic[, 2:9], diag.panel = panel.hist,
      upper.panel = panel.smooth, lower.panel = panel.cor)

# pairs函数只能显示双向关系,显示多项关系需要coplot



# coplot 显示多项关系 -----------------------------------------------------------

# * coplot显示三向关系 ----------------------------------------------------------
setwd("C:/RBook/")
Benthic <- read.table(file = "RIKZ2.txt", header= TRUE, sep="\t")

#对于不同Beach绘制Richness对于NAP的散点图;y~x的顺序确定自变量和因变量;as.factor(Beach)把海滩变量作为条件生成图形;
coplot(Richness ~ NAP | as.factor(Beach), pch=19, data = Benthic)  

#对于不同grainsize绘制Richness对于NAP的散点图;
coplot(Richness ~ NAP | grainsize, pch=19, data = Benthic)  

# * coplot 每个面板里加上一条回归线 ---------------------------------------------------
# panel.lm定义在每个面板里如何显示数据
panel.lm = function(x, y, ...) {
  tmp<-lm(y~x,na.action=na.omit)  #线性回归函数lm用来把数据暂时存储在变量tmp中,该分析中任何NAs都将被忽略;
  abline(tmp, lwd = 2)  #abline函数绘制线
  points(x,y, ...)}  #points绘制点

coplot(Richness ~ NAP | as.factor(Beach), pch=19, panel = panel.lm, data=Benthic) #对于不同Beach绘制Richness对于NAP的散点图;
coplot(Richness ~ NAP | as.factor(Beach), pch=19, span =1, panel = panel.smooth, data=Benthic)


# * coplot 显示四向关系 ---------------------------------------------------------
# panel.lm定义在每个面板里如何显示数据
panel.lm = function(x, y, ...) {
  tmp<-lm(y~x,na.action=na.omit)  #线性回归函数lm用来把数据暂时存储在变量tmp中,该分析中任何NAs都将被忽略;
  abline(tmp, lwd = 2)  #abline函数绘制线
  points(x,y, ...)}  #points绘制点

#PH对应于SDI,海拔和森林覆盖之间的关系
setwd("C:/RBook/")
pHEire<-read.table(file="SDI2003.txt", header=TRUE, sep="\t")
pHEire$LOGAlt <- log10(pHEire$Altitude)
pHEire$fForested <- factor(pHEire$Forested)
coplot(pH ~ SDI | LOGAlt * fForested, panel=panel.lm,data=pHEire)
coplot(pH ~ SDI | LOGAlt * fForested, panel=panel.lm,data=pHEire, number=2)  #LOGAlt区间的位置和数目可以通过number来调控;


# * 增加coplot的修饰 -----------------------------------------------------------
panel.lm2=function(x,y,col.line="black",lwd=par("lwd"),
                   lty=par("lwt"), ...){
  tmp<-lm(y~x,na.action=na.omit)
  points(x,y, ...)
  abline(tmp,col=col.line,lwd=lwd,lty=lty)}


CI <- co.intervals(pHEire$LOGAlt,3)
GV <- list(CI,c(2,1))

pHEire$Temperature

#根据不同的温度,将点变成不同颜色
pHEire$Temp2 <- cut(pHEire$Temperature, breaks = 2)  #breaks = 2,所以cut函数将温度数据分成两部分;
pHEire$Temp2
pHEire$Temp2.num <- as.numeric(pHEire$Temp2)  #将pHEire$Temp2从因子转为数值,因为因子不能作为色彩和灰度值;
pHEire$Temp2.num
coplot(pH ~ SDI | LOGAlt * fForested, panel=panel.lm, data=pHEire, given.values = GV, cex=1.5,pch=19, col=gray(pHEire$Temp2.num/3))


# 图形排列 --------------------------------------------------------------------
#mfrow命令可以在一个屏幕上绘制多个图形;而layout可以生成复杂的图形排列;
MyLayOut <- matrix(c(2,0,1,3), nrow = 2, ncol=2, byrow = TRUE)  #matrix函数生成一个矩阵,2行,2列,按行排列;
MyLayOut
nf <- layout(mat = MyLayOut,widths = c(3, 1),  # widths 指定列宽;
             heights = c(1, 3), respect = TRUE)  # height 指定行高,respect = TRUE确保垂直方向上的一个单位与水平方向上的一个单位相同;

layout.show(nf)

xrange<-c(min(Benthic$NAP),max(Benthic$NAP))
yrange<-c(min(Benthic$Richness),max(Benthic$Richness))

#生成第一个图形
par(mar=c(4,4,2,2))
plot(Benthic$NAP,Benthic$Richness,xlim=xrange,ylim=yrange, xlab = "NAP", ylab="Richness")

#生成第二个图形
par(mar=c(0,3,1,1))
boxplot(Benthic$NAP,horizontal=TRUE,axes=F, frame.plot=F,ylim=xrange,space=0)

#生成第三个图形
par(mar=c(3,0,1,1))
boxplot(Benthic$Richness,axes=F,ylim=yrange,space=0,horiz=TRUE)



# —— ----------------------------------------------------------------------

# 格包简介 --------------------------------------------------------------------

setwd("C:/RBook")
Env <- read.table(file="RIKZENV.txt",header = TRUE)
names(Env)
str(Env)
sum(is.na(Env))  #2975 NAs

## where are the NAs?

# Stations in each area
table(Env$Station,Env$Area)

tapply(Env$SAL,list(Env$Station,Env$Year,Env$Month),length)
tapply(Env$SAL,list(Env$Station,Env$Month),length)
tapply(Env$SAL,list(Env$Area,Env$Month),length)

# count values
ndata<-function(x) sum(!is.na(x))
tapply(Env$SAL,list(Env$Station,Env$Month),ndata)
tapply(Env$SAL,list(Env$Area,Env$Month),ndata)

# count NAs
nnas<-function(x) sum(is.na(x))
tapply(Env$SAL,list(Env$Station,Env$Month),nnas)
tapply(Env$SAL,list(Env$Area,Env$Month),nnas)



# 多面板散点图:xyplot -----------------------------------------------------------
library(lattice)
Env$MyTime<-Env$Year+Env$dDay3/365

#根据station不同来绘制SAL对MyTime的图形;
xyplot(SAL ~ MyTime | factor(Station), type="l",  # y轴 ~ x轴,管道命令后为条件变量(此处为station),条件变量通常为因子;
       strip = function(bg, ...)  #...表示将信息传递给其他特定的函数
         strip.default(bg = 'white', ...),  #对每一个带使用白色背景
       col.line=1,  #图形线条颜色
       data = Env)

xyplot(SAL ~ MyTime | factor(Station), data = Env)
xyplot(SAL ~ MyTime | factor(Station), type="l", strip = TRUE, col.line=1, data = Env)
xyplot(SAL ~ MyTime | factor(Station), type="l", strip = FALSE, col.line=1, data = Env) #查看strip功能,strip用来绘制带状;


# 多面板盒型图:bwplot -----------------------------------------------------------
bwplot(SAL ~ factor(Month) | Area,
       strip = strip.custom(bg = 'white'),
       cex = .5, layout = c(2, 5),
       data = Env, xlab = "Month", ylab = "Salinity",
       par.settings = list(
         box.rectangle = list(col = 1),
         box.umbrella  = list(col = 1),
         plot.symbol   = list(cex = .5, col = 1)))

bwplot(SAL ~ factor(Month) | Area, layout = c(2, 5), data = Env) #若采用黑白作图,则上面的代码可以简化为这个;



# 多面板点图:dotplot -----------------------------------------------------------
dotplot(factor(Month) ~ SAL  | Station,
        subset = Area=="OS", jitter.x = TRUE,  #subset是用来选定全部数据的一个子集;jitter.x = TRUE表示当多个观察值在同一月份相同的时候,在水平方向增加一些变化;
        data = Env, strip = strip.custom(bg = 'white'),
        col = 1, cex = 0.5, ylab = "Month",
        xlab = "Salinity")

dotplot(SAL ~ factor(Month) | Station,    
        subset = Area=="OS", jitter.x = T,
        data = Env, strip = strip.custom(bg = 'white'),
        col = 1, cex = 0.5, xlab = "Month",
        ylab = "Salinity")    #与上一个相比将x轴y轴对调一下;



# 多面板直方图: histogram -------------------------------------------------------
histogram( ~ SAL | Station, data = Env,
           subset = Area=="OS", layout = c(1,4),  #layout里面为1列2行的布局,与先行后列不同
           nint = 30, xlab = "Salinity", strip = FALSE,  #nint是条形的数目
           strip.left = TRUE, ylab="Frequencies")  #通过strip = FALSE, strip.left = TRUE将带状移到了面板左边;


#Example 1
xyplot(SAL ~ Month | Year, data = Env,  
       type = c("p"), subset = (Station =="GROO"),  #type有三个函数,分别是p,g,smooth;相当于函数执行了panel.xyplot,panel.grid,panel.loess
       xlim = c(0, 12), ylim = c(0, 30),pch = 19,
       panel = function (...){
         panel.xyplot(...)  #画出数据点
         panel.grid(..., h = -1, v = -1)  #panel.grid加网格线,h和v为正值表示水平与垂直网格线的数目;若为负值则网格与轴坐标对其;
         panel.loess(...)}, span = 0.9)  #panel.loess加拟合线,span表示拟合线的平滑程度;

#Example 2
#使用不同的颜色和大一点的点来表示潜在异常值,方法1和方法2是殊途同归
setwd("C:/RBook")
library(lattice)
Env <- read.table(file="RIKZENV.txt",header = TRUE)
#方法1
dotplot(factor(Month) ~ SAL | Station, pch = 16,
        subset = (Area=="OS"), data = Env,
        ylab = "Month", xlab = "Salinity",
        panel = function(x,y,...) {
          q1 <- summary(x,na.rm=TRUE)[2]
          q3 <- summary(x,na.rm=TRUE)[5]
          R <- q3 - q1
          L <- median(x,na.rm=TRUE) - 3 * (q3 - q1)
          MyCex <- rep(0.4,length(y))
          MyCol <- rep(1,length(y))
          MyCex[x < L] <- 1.5
          MyCol[x < L] <- 2
          panel.dotplot(x,y, cex = MyCex, col = MyCol, ...)})

# 方法2
dotplot(factor(Month) ~ SAL | Station, pch = 16,
        subset = (Area=="OS"), data = Env,
        ylab = "Month", xlab = "Salinity",
        panel = function(x, y, ...) {
          Q <- quantile(x, c(0.25, 0.5, 0.75) ,  #
                        na.rm = TRUE)
          R <- Q[3] - Q[1]
          L <- Q[2] - 3 * (Q[3] - Q[1])  #L为盐度数据的截止水平,即中位数减去第三四分位数和第一四分位数差的三倍
          MyCex <- rep(0.4, length(y))
          MyCol <- rep(1, length(y))
          MyCex[x < L] <- 1.5  #当盐度低于标准修改点的尺寸
          MyCol[x < L] <- 2    #当盐度低于标准修改点的颜色
          panel.dotplot(x, y, cex = MyCex, 
                        col = MyCol, ...)})



# 多面板 PCA 分析双标图 -----------------------------------------------------------
setwd("C:/RBook")
Sparrows<-read.table(file="Sparrows.txt", header=TRUE)
names(Sparrows)
str(Sparrows)
library(lattice)
xyplot(Wingcrd ~ Tarsus | Species * Sex,  #管道命令后面是两个条件变量
       xlab = "Axis 1", ylab = "Axis 2", data = Sparrows,
       xlim = c(-1.1, 1.1), ylim = c(-1.1, 1.1),
       panel = function(subscripts, ...){
         zi <- Sparrows[subscripts, 3:8]
         di <- princomp(zi, cor = TRUE)
         Load <- di$loadings[, 1:2]
         Scor <- di$scores[, 1:2]
         panel.abline(a = 0, b = 0, lty = 2, col = 1)
         panel.abline(h = 0, v = 0, lty = 2, col = 1)
         for (i in 1:6){
           llines(c(0, Load[i, 1]), c(0, Load[i, 2]), 
                  col = 1, lwd = 2)
           ltext(Load[i, 1], Load[i, 2], 
                 rownames(Load)[i], cex = 0.7)}
         sc.max <- max(abs(Scor))
         Scor <- Scor / sc.max
         panel.points(Scor[, 1], Scor[, 2], pch = 1,
                      cex = 0.5, col = 1)
       })



# 三维点图/表面图/等高线图 -----------------------------------------------------------
setwd("C:/RBook")
library(lattice)
Env <- read.table(file="RIKZENV.txt",header = TRUE)   
cloud(CHLFa ~ T * SAL | Station, data = Env,
      screen = list(z = 105, x = -70),
      ylab = "Sal", xlab = "T", zlab = "Chl. a",
      ylim = c(26,33),
      subset = (Area=="OS"),
      scales = list(arrows = FALSE))




# 常见问题 --------------------------------------------------------------------


# * 改变面板顺序 ----------------------------------------------------------------
setwd("C:/RBook")
Hawaii <- read.table("waterbirdislandseries.txt", header = TRUE)
library(lattice)
names(Hawaii)
Birds <- as.vector(as.matrix(Hawaii[,2:9]))  #as.vector命令不能应用于数据框;所以as.matrix命令首先将数据转化为一个矩阵,然后再由as.vector将其转化为一个长向量!
Time <- rep(Hawaii$Year, 8)  #rep函数的作用是生成一个单独的长向量;
MyNames <- c("Stilt_Oahu","Stilt_Maui","Stilt_Kauai_Niihau","Coot_Oahu","Coot_Maui","Coot_Kauai_Niihau","Moorhen_Oahu","Moorhen_Kauai")
ID <- rep(MyNames, each = 48)

xyplot(Birds ~ Time|ID, ylab = "Bird abundance", layout = c(3, 3), type = "l", col = 1)

#通过改变levels顺序就可以改变这些面板的顺序;
ID2 <- factor(ID, levels=c("Stilt_Oahu","Stilt_Kauai_Niihau","Stilt_Maui","Coot_Oahu","Coot_Kauai_Niihau","Coot_Maui","Moorhen_Oahu","Moorhen_Kauai"))
xyplot(Birds ~ Time|ID2, ylab = "Bird abundance",layout = c(3, 3), type = "l", col = 1)


# * 改变坐标轴界限刻度 -------------------------------------------------------------
xyplot(Birds ~ Time|ID2, ylab = "Bird abundance",
       layout = c(3, 3), type = "l", col = 1,
       scales = list(x = list(relation = "same"),
                     y = list(relation = "free"),
                     tck=-1))  #tck是刻度,负朝里,正朝外;数字代表长短

# * 一个面板中绘制多条线 ------------------------------------------------------------
#将同一种鸟的所有时间序列陈列在一个单独的面板中
Species <-rep(c("Stilt","Stilt","Stilt","Coot","Coot","Coot","Moorhen","Moorhen"),each = 48)
xyplot(Birds ~ Time|Species, ylab = "Bird abundance",
       layout = c(2, 2), type = "l", col = 1,
       scales = list(x = list(relation = "same"),
                     y = list(relation = "free")),
       groups = ID, lwd=c(1,2,3))




# 更新图形 --------------------------------------------------------------------
MyPlot <- xyplot(Birds ~ Time|Species, ylab = "Bird abundance",
                 layout = c(2, 2), type = "l", col = 1,
                 scales = list(x = list(relation = "same"),
                               y = list(relation = "free")),
                 groups = ID, lwd=c(1,2,3))

print(MyPlot)
update(MyPlot, layout=c(3,3)) #对象的很多属性可以通过update函数来修改!可以保持原始图不变。


相关文章

  • 《R語言初學者指南》學習筆記

    第一章 引言 第二章 R 中的数据输入 使用矩阵结合数据 使用数据框(data.frame函数)结合数据 使用l...

  • 第五項修煉之團隊學習

    學習是一种語言,也就是說,學習使用這种語言和他人交流,所以,使用語言是學習語言最有效的方法。

  • 我的语言学习感想

    在燎原学院的萬國學院裡學習和法語,德語,現在在學習西班牙語和拉丁語,太貪心了,想把每一門語言都掌握好,當初的目...

  • 自學烏克麗麗-高頻小套路

    # 學烏克麗麗-自學筆記 學習的心情一定要開心,不要有壓力。 1. 設定學習目的,ex:自彈自唱(自嗨) 2. 選...

  • 語言是思想的載體

    今天看了一個陳丹青先生關於語言的演講視頻,我接受到他演講的信息大概是:人要語言,不僅需要學習母語,還需要學習...

  • Kotlin學習筆記

    變數(variable) 1.不可改變的變數 2.可以改變的變數 example: 方法 預設是final, pu...

  • 學習筆記1

    #筆記 羅胖今天講新書《事實》還有每天聽書的《心智》讓我大受啟發,立刻被我列為必讀書單。 《事實》讓我們用長時段看...

  • 學習筆記分享

    恬淡虛無 真氣從之,宇宙法則,馬太效應:好的人會越來越好,壞的人越來越壞 淡是平淡 淡淡的 反義詞:酸苦甘辛甜 重...

  • 筆墨讀書——讀通札記(504)

    讀中華點校本《卷四十九》,感:1、筆墨讀書。人言:不動筆墨不讀書;再言:好記性不如爛筆頭;更有,孔子《論語》曰:學...

  • 我使用 Vue 的起手式(vue-cli + sass + bo

    初學者筆記 Step 1 安裝 vue-cli npm install -g vue-cli Step 2 建...

网友评论

      本文标题:《R語言初學者指南》學習筆記

      本文链接:https://www.haomeiwen.com/subject/banyxktx.html