生态学数据处理常用R语言代码
使用R来处理生态学数据越来越受到科研工作者的青睐,语义编程风格、漂亮的出图效果,能直接俘获众多用户。本文将生态学数据处理中经常会使用到的功能做个搜集整理。
本文假设读者有一些R的基础知识,对于R的编程规则有所了解。文章内容包括:
一、准备工作
二、数据分布形式
三、数据探索
四、均值比较
五、趋势检验
六、用回归分析不同因子的贡献大小
放一张R基础绘图函数绘制的图镇文
一、准备工作
# 清理内存中所有变量
rm(list = ls())
# 设置工作目录
setwd("E:/BiostatisticsR/2016")
# 读取工作目录中txt文件
Data <- read.table("temporary.txt", header=T) #header=T表示第一行是表头
#列出表头(变量名)
names(Data)
#显示前几条记录
head(Data)
#散点图
plot(Data$NMDS1,type="o",pch=1)
#创建变量
x <- c(1:25)
y <- c(1:25)
最简单的绘图代码
#绘图符号及颜色
plot(x=x,y=y,pch=c(1:25),col=c("red","blue","orange","green"),cex=1.5)
points(x=(1:25),y=c(25:1),col="black")
text(x=5,y=20,"look at me")
#箱式图
boxplot(Data$NMDS1~Data$Year)
二、 数据分布形式
#概率密度函数 dnorm(n, mean = 0, sd = 1)
#dbinom(n, mean = 0, sd = 1)
#dnorm(1)
#dnorm(1, mean=1, sd=1)
#dnorm(c(1:10),mean=1,sd=1)
#累积密度函数pnorm(n, mean = 0, sd = 1)
#pnorm(c(1,2,3,4))
#产生序列 seq
#seq(min,max,length)
#seq(1,10,length=1000)
#产生随机数rnorm(n, mean = 0, sd = 1)
rnorm(23, mean = 0, sd = 1)
#取样函数 sample(x, size, replace = FALSE, prob = NULL)命令是从x中随机抽取size大小的样本
for(i in c(1:10)){
print(sample(c(1:10),2))
}
#二项式分布:dbinom(x, size, prob, log = FALSE)
#已知某批鸡蛋的孵出率prob为0.9,抽取size为5个鸡蛋检查其孵化情况,发现最终x=3个鸡蛋孵化,求二项分布的概率。
#R中的求解如下:
#dbinom(3,5,0.9,log=F)
for(i in c(1:9))
{
if(i==1){
plot(c(1:1000),dbinom(c(1:1000),1000,0.25),type="l",col=1)
lines(c(1:1000),dbinom(c(1:1000),2000,0.25),type="l",col=2)
}
else
{lines(c(1:1000),dbinom(c(1:1000),1000,i/10),type="l",col=i)}
}
# 绘制正态分布图形
plot(seq(-5,5,length=1000),
dnorm(seq(-5,5,length=1000),
mean = 0, sd = 0.5),
type="l",col=1)
lines(seq(-5,5,length=1000),dnorm(seq(-5,5,length=1000), mean = 0, sd = 1), type="l",col=2)
lines(seq(-5,5,length=1000),dnorm(seq(-5,5,length=1000), mean = 0, sd = 2), type="l",col=3)
lines(seq(-5,5,length=1000),dnorm(seq(-5,5,length=1000), mean = 0, sd = 3), type="l",col=4)
abline(v=-2,col="blue")
lines(seq(-5,5,length=1000),dnorm(seq(-5,5,length=1000), mean = -2, sd = 3), type="l",col=4)
测试数据不同分布形式
m.pop <- 5 #设定总体均值
sd.pop <- 2 #设定总体方差
pop <- rnorm(3000,mean=m.pop, sd=sd.pop) #生成平均值为5,方差为2的总体
t <- vector(mode="numeric",length=0) #存放t值
x2 <- vector(mode="numeric",length=0) #存放卡方值
f <- vector(mode="numeric",length=0) #存放F值
samples <- 4000 #随机取样次数
n <- 15 #每个样本含量
#随机取样
for(i in c(1:samples))
{
y <- sample(pop, n, replace = FALSE, prob = NULL)
mean.y <- mean(y)
sd.y <- sd(y)
t[i] <- (mean.y-m.pop)/sd.y # t=(样本均值-总体均值)/样本标准差
x2[i] <- ((n-1)*var(y))/(sd.pop^2) # x2 = (n-1)样本方差/总体方差
}
#画直方图及密度图
par(mfrow=c(1,2))
summary(t)
hist(t,freq=F,breaks=seq(-1.5,1.5,by=0.005))
lines(density(t),col=2) #density(x,bw)函数给出的是一个核密度估计(KDE) 百度百科:《核密度图详解》
plot(density(t,bw=0.1))
lines(density(t,bw=0.5),col=2)
lines(density(t,bw=1),col=3)
hist(x2,freq=F)
lines(density(x2))
#对t和x2做正态性监测
shapiro.test(t)
shapiro.test(x2) #零假设:服从正态分布;备选假设:不服从正态分布
#画自由度分别为1:10,300的t分布曲线,和标准正态分布
for(i in c(1:10))
{
if(i==1)
{plot(seq(-5,5,length=1000),dt(seq(-5,5,length=1000), df=i, ncp=0), type="l",col=i,ylim=c(0,0.45))}
else{
lines(seq(-5,5,length=1000),dt(seq(-5,5,length=1000), df=i, ncp=0), type="l",col=i)
}
}
lines(seq(-5,5,length=1000),dt(seq(-5,5,length=1000), df=300, ncp=0), type="l",col=i)
lines(seq(-5,5,length=1000),dnorm(seq(-5,5,length=1000), mean = 0, sd = 1), type="l",col=1, lty=3,lwd=3)
abline(v=0,col="lightgray")
画自由度分别为1:10,300的t分布曲线,和标准正态分布
#卡方分布rchisq(n,df,ncp=0 )
for(i in c(1:10))
{
if(i==1)
{plot(seq(0,40,length=1000),dchisq(seq(0,40,length=1000), df=i, ncp=0), type="l",col=i,ylim=c(0,0.5), xlim=c(0,40))}
else{
lines(seq(0,40,length=1000),dchisq(seq(0,40,length=1000), df=i, ncp=0), type="l",col=i)
}
}
lines(seq(0,40,length=1000),dchisq(seq(0,40,length=1000), df=20, ncp=0), type="l",col=1,lty=3,lwd=3)
# F分布
######随机抽样
pop1 <- rnorm(3000,mean=5, sd=1.5)
pop2 <- rnorm(3000,mean=7, sd=2)
samples <- 3000 #随机取样次数
n1 <- 15 #每个样本含量
n2 <- 25 #每个样本含量
#随机取样
for(i in c(1:samples))
{
y1 <- sample(pop1, n1, replace = FALSE, prob = NULL)
y2 <- sample(pop2, n2, replace = FALSE, prob = NULL)
var.y1 <- var(y1)
var.y2 <- var(y2)
f[i] = (var.y1/1.5)/(var.y2/2)
}
#画直方图及密度图
hist(f,freq=F)
lines(density(f))
#对t和x2做正态性监测
shapiro.test(f)
plot(seq(0,4,length=1000),df(seq(0,4,length=1000), df1=4, df2=20, ncp=0), type="l",col=1,ylim=c(0,0.8), xlim=c(0,4))
lines(seq(0,4,length=1000),df(seq(0,4,length=1000), df1=20, df2=4, ncp=0), type="l",col=2)
n <- 100
y <- rnorm(n, 5, 1)
width <- 0.01
scal <- seq(-2, 12, by = 0.01)
ll <- length(scal)
den_y <- density(y, n = ll, from = -2, to = 12) # here defines the range and width
plot(scal, den_y$y, type = "l")
# use numerical integration
# for example, you need pr(a < x < b)
a <- 2
b <- 4
begin <- which.max(den_y$x[den_y$x < a])
end <- which.max(den_y$x[den_y$x < b])
prob <- sum(den_y$y[begin:end]*width)
# confirm
true_prob <- pnorm(4, 5, 1) - pnorm(2, 5, 1) # increase n to 100000, true_prob = prob. In small sample, they are different
x=rnorm(100)
plot(density(x))
z=density(x)
z$x
z$y
三、 数据探索
# 读取工作目录中txt文件
Data <- read.table("temporary.txt", header=T) #header=T表示第一行是表头
temp.data <- Data$NMDS1
summary(temp.data)#均值,最小值,中位数,一分位数,三分位数,最大值
mean(temp.data,na.rm=T,trim=0)#算术平均数
range(temp.data) #最大值最小值
quantile(temp.data,probs=c(0,0.05,0.5,0.75,1))#分位数
boxplot(temp.data) #箱式图
var(temp.data) #方差
sd(temp.data) #标准差 开根号
plot(density(temp.data)) #画密度函数
lines(seq(min(temp.data),max(temp.data),length=1000),#正态分布
dnorm(seq(min(temp.data),max(temp.data),length=1000),
mean = mean(temp.data), sd = sd(temp.data)),
type="l",col=2)
rug(temp.data) #添加样本
#正态性检验
shapiro.test(temp.data)#零假设:服从正态分布;备选假设:不服从正态分布
qqnorm(temp.data) #画QQ图
x<-c(1,2,3,4,5)
y<-c(1,2,3,4,5)
abline(lm(y~x),col=2,lwd=2)
temp.data <- as.data.frame(
scale(Data$WT, center=T, scale=T)
)
colnames(temp.data)<-c("NMDS1")
rownames(temp.data) <- c(5:84)
shapiro.test(log10(Data$Eutro))
plot(density(Data$Eutro)) #画密度函数
自定义开N次方函数
sqrtn <- function(x, n){
x^(1/n) #开N次方函数
}
sqrtn(2,0.89)
NMDS.T <- as.data.frame(scale(Data, center=T, scale=T)) #中心标准化
NMDS.T <- log(Data+100,base=10) #对数转换
NMDS.T <- sqrt(Data+100) #平方根
plot(NMDS.T[,2])
cwt <- Data$CWT
cwt <- Data[,c(1,2,5,6,7,10)]
cwt <- cwt[,-2]
colnames(cwt)[7] <- "WT"
cwt[,7] <- Data$WT
cwt.mean <- mean(cwt)
cwt.mean^(1/2)
plot(NMDS.T,type="l")
Mann_Kendall(Data$CWT)
cor(Data$CWT,Data$WT) #相关系数
四、均值比较
# t检验
# 1、单样本t检验(one sample t-test)
# 已知总体平均值μ,但总体标准差σ未知
# 检查前提条件
# 正态分布
#已知夏天的温度是22度。
#人家都说江苏没有春天,只有冬天和夏天
#现有太湖1992-2012的春天温度,请验证太湖春天温度和夏天是否一致。。。。
#解析:总体均值已知,但方差未知,使用单样本t检验比较均值
#准备数据
temp.data <- as.data.frame(tapply(Data$WT,list(Data$Year),mean))
colnames(temp.data) <- "WT"
test.data <- temp.data$WT
mean.1 <- mean(test.data) ## 温度平均值
sd.1 <- sd(test.data) ## 温度的方差
max.1 <- max(test.data)
min.1 <- min(test.data)
shapiro.test(test.data) #零假设:服从正态分布;备选假设:不服从正态分布
#检验正态分布的直观表现
#思想:先画密度柱形图
# 后画密度曲线
# 添加一条相应的正态分布密度曲线
hist(test.data,freq=F)
lines(density(test.data),lty=3,lwd=2,col="red") #画密度函数
lines(
seq(min.1,max.1,length=10), #x轴
dnorm( #求正态分布下的密度
seq(min.1,max.1,length=10),
mean = mean.1,
sd=sd.1
),
type="l",
lwd=2,
col="blue"
)
t.test(test.data, mu=22, var.equal=FALSE) #零假设:两个平均值相等;备选假设:两个均值不相等。
t.test(test.data, mu=30, var.equal=FALSE) #零假设:两个平均值相等;备选假设:两个均值不相等。
#mu表示平均值,var.equal = FALSE表示方差未知
rm(test.data,max.1, min.1,mean.1,sd.1)
# 2、两样本t检验(two-sample t-test)
# 检查前提条件
# 正态性检验
# Bartlett Test方差齐性检验(参数)
# 要将两个欲对比数据放在一列。。。。。。。。。。。
# 方差齐性分析对离群点非常敏感。
NMDS1 <- as.data.frame(tapply(Data$NMDS1,list(Data$Year),mean))
NMDS2 <- as.data.frame(tapply(Data$NMDS2,list(Data$Year),mean))
NMDS1 <- NMDS1[,1]
NMDS2 <- NMDS2[,1]
shapiro.test(NMDS1) #零假设:服从正态分布;备选假设:不服从正态分布
shapiro.test(NMDS2) #零假设:服从正态分布;备选假设:不服从正态分布
temp.data <- data.frame(value.test=c(NMDS1,NMDS2), #第一个变量,#第二个变量
group=factor(
c(rep(1,length(NMDS1)),
rep(2,20)
)
)
)
bartlett.test(value.test~group,data=temp.data)
#零假设:方差齐。#备选假设:方差不齐
rm(temp.data)
#独立样本t检验
t.test(NMDS1,NMDS2, #零假设:两个平均值相等;备选假设:两个均值不相等。
var.equal=F, #方差齐性检验
alternative="two.sided" #检验方式:双尾、大于、小于
)
# 3、成对样本t检验
# 条件如前
t.test(NMDS1,NMDS2, paired=TRUE) #零假设:两个平均值相等;备选假设:两个均值不相等。
#其他案例
#成对t检验有意思的地方
serial1 <- rnorm(1000)
hist(serial1,freq=F)
lines(density(serial1),lty=3,lwd=2,col="red") #画密度函数
lines(
seq(-3,4,length=1000), #x轴
dnorm( #求正态分布下的密度
seq(-3,4,length=1000),
mean = 0,
sd=1
),
type="l",
lwd=2,
col="blue"
)
serial1 <- serial1[order(serial1)]
serial2 <- rev(serial1)
t.test(serial1,serial2, #零假设:两个平均值相等;备选假设:两个均值不相等。
var.equal=T, #方差齐性检验
alternative="two.sided" #检验方式:双尾、大于、小于
)
t.test(serial1, serial2, var.equal=T, paired=TRUE)
t.test(serial1, serial2+2, var.equal=T, paired=TRUE)
# 4、非参数t检验
# 在无法满足t检验的前提下
# 优点:不需要满足任何分布
# 缺点:检验功效不强
# Wilcoxon秩和检验(Mann-Whitney U检验)
wilcox.test(Data$NMDS1,Data$NMDS2, paired=T) #零假设:两个平均值相等;备选假设:两个均值不相等。
方差分析(ANOVA)
#1、单因素方差分析
#用于比较多组均值之间的差异显著性检验
#思想:将变异分解为组间和组内。
#要求:1、各组观测值服从正态分布或者近似正态分布
# 2、各组之间方差具有齐性。
# 3、各组之间相互独立。
#gl(n,k,length=n*k,labels=1:nordered=FALSE),n 为水平数,k为重复次数.
#我们的数据是1992-2012年四个采样点的数据,请比较每五年温度变化是否显著。
#解析:每5年一组就有4个处理,1992-96、1997-01、2002-07、2008-2012。t检验已经不适合
Data$treat <- gl(4,20,80,labels=c("A", "B", "C","D"))
#gl(n, k, length = n*k, labels = seq_len(n), ordered = FALSE)
#n处理数
#k重复数
Data$sites <- rep(c(1,3,4,5),20)
table(Data$treat) #计算不同处理的个数
tapply(Data$WT,list(Data$treat),mean)
tapply(Data$WT,list(Data$treat),sd)
bartlett.test(WT~treat, data=Data) #零假设:方差齐
qqPlot(lm(WT~treat,data=Data)) #正态性检验:要求所有点均落在95%置信区间内。需要car包支持
#否则需要一个一个验证
kruskal.test(WT~treat,data=Data) #方差不齐时使用,秩和检验 null: 有区别 Alternative:没区别
m1 <- aov(WT~treat,data=Data) #零假设:没有差异;备选假设:有差异
summary(m1)
outlierTest(m1) #离群点分析(需要car包支持)
#多重比较
TukeyHSD(m1) #Tukey多重比较是比较多的一种
plot(TukeyHSD(m1)) #假如置信区间包括0,则说明二者差异不显著。
boxplot(WT~treat,data=Data)
tuk <- glht(m1, linfct=mcp(treat="Tukey"))#需要multcomp软件包支持
plot(cld(tuk, level=0.05),col="lightgrey",xlab="处理组", ylab="温度(OC)")#相同字母表示差异不显著
t.test(Data$WT[Data$treat=="B"],Data$WT[Data$treat=="C"])
#单因素协方差分析
#ANCOVA
#不同采样点时间不一样,是否会影响到结果呢?
#采样时间不一样,属于非人为能控制,因此考虑作为协变量
#
#实现方式1:定量
m1<-aov(WT~sites+treat,data=Data) #零假设:没有差异;备选假设:有差异
summary(m1)
#实现方式2:直观
ancova(WT~sites+treat,data=Data) #零假设:没有差异;备选假设:有差异。HH包
#如果斜率相等,说明该协变量对总体没有影响
library(effects)
effect("treat",m1)
#双因素方差分析
#目的:不同点位间、不同年份之间的温度是否有差异?
#解析:不同处理是一个因素,不同点位是一个因素
#采用双因素方差分析
tapply(Data$WT, list(Data$treat, Data$sites), FUN=mean) #求均值
tapply(Data$WT, list(Data$treat, Data$sites), FUN=sd) #求方差
bartlett.test(WT~sites, data=Data) #零假设:方差齐
bartlett.test(WT~treat, data=Data) #零假设:方差齐
qqPlot(lm(WT~treat*sites,data=Data)) #正态性检验:要求所有点均落在95%置信区间内
m1 <- aov(WT~treat*sites, data=Data)
summary(m1)
#差异可视化
interaction.plot(Data$treat, Data$sites,
Data$WT, type="b",
col=c("red","blue","black","gray"),
pch=c(16,18,12,5),
main="比较"
)
interaction2wt(WT~treat*sites,data=Data) #需要HH包支持
#以上方差分析基本基于aov函数
#线性回归做方差分析
m1 <- lm(WT~treat*sites,data=Data)
anova(m1)
五、趋势检验
# 读取工作目录中txt文件
Data <- read.table("temporary.txt", header=T) #header=T表示第一行是表头
temp.data <- as.data.frame(tapply(Data$WT, list(Data$Year), FUN=mean)) #求均值
colnames(temp.data) <- c("WT")
temp.data$Year <- as.numeric(rownames(temp.data))
#M-K检验:Mann-Kendall趋势检验
#需要样本遵循一定的分布、不受少数异常值的干扰
#适用于水文、气象等非正态分布的数据。
MannKendall(temp.data$WT) #零假设:没有趋势;备择假设:有趋势
plot(temp.data$WT,type = "1")
#线性趋势
#拟合直线
plot(temp.data$Year,temp.data$WT,type="o")
m1 <- lm(WT~Year, data=temp.data)
summary(m1)
#平滑函数
#不能定量,只能定性
plot(temp.data$Year, temp.data$WT, type="o")
lines(lowess(x=temp.data$Year, temp.data$WT), lty=4, lwd=2,col="red")
#分段回归
library("segmented")
x <- c(1:10,10:1,1:10)
y <- c(1992:2021)
m1 <- lm(x~y)
plot(y,x)
M.break <- segmented(m1, seg.Z=~y, psi=list(y=c(1993,2000)))
plot(M.break,add=TRUE,link=FALSE,lwd=2, xaxt="n")
summary(M.break)
#降季节趋势
Data <- read.table("a1.txt", header=T) #header=T表示第一行是表头
Cal <- ts(Data$SunShine, frequency=12)
stl1 <- stl(Cal, "per")
plot(stl1)
names(stl1)
d <- summary(stl1)
names(d)
d <- as.data.frame(stl1$time.series)$trend
plot(d)
stl1$time.series
#M-K突变检验
#根据魏凤英老师书编写代码
#20151012根据网友提示修改代码
#[email protected]
#Mann_Kendall(序列数据,开始年份)
Mann_Kendall <- function(timeserial,start){#参数传递为时间序列和开始年份
Mann_Kendall_sub <- function(timeserial){#计算秩
r <- c()
s <- c()
U <- c()
for(i in 2:length(timeserial))
{r[i] <- 0
for(j in 1:i)
{
if(timeserial[i]>timeserial[j]){r[i]=r[i]+1}
}
s[i] <- 0
for (ii in 2:i){
s[i] <- s[i]+r[ii]
}
U[i] <- 0
U[i] <- (s[i]- (i*(i+1)/4))/sqrt(i*(i-1)*(2*i+5)/72)
}
r[1] <- 0
s[1] <- 0
U[1] <- 0
LST <- list(r = r, s = s, U = U)
return (LST)
}
timeserial_rev <- rev(timeserial)
y1 <- Mann_Kendall_sub(timeserial)
y2 <- Mann_Kendall_sub(timeserial_rev)
y2$U <- -(rev(y2$U))
LST <- list(UF=y1,UB=y2)
plot(x=c(start:(start-1+length(timeserial))),y=y1$U,type="l",lwd=2, ylim=c(min(y1$U,y2$U,-1.96),max(y1$U,y2$U,1.96)),xlab="序列",ylab="UF=黑;UB=红")
points(x=c(start:(start-1+length(timeserial))),y=y2$U,type="l",lty=3,col="red",lwd=2)
abline(h=1.969,lty=4,lwd=0.5)
abline(h=-1.96,lty=4,lwd=0.5)
abline(h=0,col="gray",lwd=0.5)
return(LST)
}
temperature <- temp.data$WT
d<-Mann_Kendall(temperature,1900)
六、用回归分析不同因子的贡献大小
#问题的提出:请分析水温、电导率、营养水平对第一轴的贡献大小
#考虑通过多元分析来解决
#1、先分析模型,检查共线性
#2、检验模型显著性及残差分布状态
#3、对比不同变量的贡献
# 方差膨胀因子(VIF)计算函数
# Written by Qingyi @20150605
# 方差膨胀因子计算公式及定义见:http://en.wikipedia.org/wiki/Variance_inflation_factor
# 需要传入拟比较的变量和所在的数据集
VIF <- function(variable,data){
var.nums <- length(variable) #获取变量个数
vif.table <- matrix(,nrow=var.nums,ncol=2) #声明一个矩阵,用于返回计算结果
for(i in 1:var.nums) #循环计算各个变量的VIF
{
#以下部分用于对字符串进行拼接,用于执行lm()函数。代码并不是最优。
text=""
for(ii in variable[-i])
{
text=paste(text,ii,sep="+")
}
text=paste(text, ",data=",sep="")
text=paste(text,data,sep="")
text=paste(variable[i],substr(text, 2, nchar(text)),sep="~")
text=paste("temp.lm <- lm(",text,sep="")
text=paste(text,")",sep="")
#字符串拼接结束。
eval(parse(text=text)) #执行lm()
temp.d <- summary(temp.lm) #取得r2所在数据集
vif.table[i,1] <- variable[i] #标明变量
vif.table[i,2] <- round(1/(1-temp.d$r.squared),2) #给出具体的数字,显示两位小数
}
colnames(vif.table) <- c("Var.", "VIF") #给表格Header
vif.table <- as.data.frame(vif.table) #转化为数据框
return(vif.table) #返回值
}
names(Data)
VIF(c("WT","Cond","Eutro"),"Data") #以10为阈值
l.model <- lm(NMDS1~WT+Cond+Eutro,data=Data)
residplot(l.model)
summary(l.model)
par(mfrow=c(2,2))
plot(l.model)
names(l.model)
shapiro.test(as.data.frame(l.model$residuals)[,1]) #零假设:服从正态分布;备选假设:不服从正态分布
#W = 0.97704, p-value = 0.1593
#符合正态分布
#全子集回归分析
#选择最佳模型
#主要是通过调整后的R平方来衡量
#需要leaps包支持
#全子集回归可用leaps包中的regsubsets()函数实现。你能通过R平方、调整R平方或
#Mallows Cp统计量等准则来选择“最佳”模型
library(leaps)
par(mfrow=c(1,1),oma=c(0.5,0.5,0.5,0.5), mar=c(0.5,0,0,0), cex=0.8, mgp=c(2.3,0.8,0),tck=-0.01, family = 'serif')
leaps.Raw <- regsubsets(NMDS1~WT+Cond+Eutro,data=Data,nbest=3)
plot(leaps.Raw,scale="adjr2")
#根据图中的显示选择R最大的组合
# 相对重要性计算函数
# 20151007摘自《R语言实战》
# 可参考:Johnson(2000, Multivariate Behavioral Research, 35, 1-19)
# @Qingyi
relweights <- function(fit, ...){
R <- cor(fit$model)
nvar <- ncol(R)
rxx <- R[2:nvar, 2:nvar]
rxy <- R[2:nvar, 1]
svd <- eigen(rxx)
evec <- svd$vectors
ev <- svd$values
delta <- diag(sqrt(ev))
lambda <- evec %*% delta %*% t(evec)
lambdasq <- lambda^2
beta <- solve(lambda) %*% rxy
rsquare <- colSums(beta^2)
rawwgt <- lambdasq %*% beta ^2
import <- (rawwgt/rsquare)*100
lbls <- names(fit$model[2:nvar])
rownames(import) <- lbls
colnames(import) <- "Weights"
barplot(t(import), names.arg=lbls, ylab="% of R-Square", xlab="Predictor Variables", main="Relative Importance of Predictor Variables", sub=paste("R-Square", round(rsquare, digits=5)),...)
return(import)
}
names(Data)
VIF(c("CWT","WT","ss","TP","Cond","Eutro"),"Data")
VIF(c("Cloud","Global","Diffuse","Global"),"Data")
##绘制残差函数
##摘录自《R语言实战》
##Qingyi@20151007
residplot <- function(fit, nbreaks=10){
z <- rstudent(fit)
hist(z, breaks=nbreaks, freq=F, xlab="Studentized Residual", main="Distribution of Errors")
rug(jitter(z), col="brown")
curve(dnorm(x,mean=mean(z),sd=sd(z)), add=T, col="blue", lwd=2)
lines(density(z)$x, density(z)$y, col="red", lwd=2, lty=2)
legend("topright", legend=c("Normal Curve", "Kernel Density Curve"), lty=1:2, col=c("blue", "red"), cex=0.7)
}
s.cor <- Data[,c(2,12,15,16)]
plot(s.cor)
#第一种方法:通过标准化的系数比较
s.cor.T <- as.data.frame(scale(s.cor, center=T, scale=T))
l.model <- lm(NMDS1~WT+Cond+Eutro,data=s.cor.T)
summary(l.model)
#第二种方法:通过比较偏相关系数
#需要corpcor包支持
library("corpcor")
xcor <- cor(s.cor)
xpcor <- cor2pcor(xcor)
xpcor
#第三种方法:通过相对重要指数
#相对权重(relative weight)衡量各个因子的重要性#############
#
#对所有可能子模型添加一个预测变量引起R平方平均增加量的近似值。
#其他方法可以根据相关系数、但是适用于预测变量之间不相关的情况
#还可以通过标准化数据之后回归系数比较
relweights(l.model,col="red")
#数据标准化之后结果与前面一致
library("relaimpo")
calc.relimp(l.model, type="lmg") #需要relaimpo包支持
#广义可加模型(GAM)
#对数据分布不做特别要求
#使用数据说话
#缺点:
#晦涩难懂
library("mgcv")
gamc <- gam(NMDS1~s(WT)+s(Cond)+s(Eutro),data=Data)
summary(gamc)
gam.check(gamc)
AIC(gamc) #用于选择最优模型
plot(gamc,page=1)
d <- as.data.frame(predict(gamc,type="terms"))
plot(d$`s(WT)`,type="l",ylim = c(-1,1))
abline(h=0,col="gray")
lines(d$`s(Eutro)`,type = "1",col="red")
#*****************************************************
# 中科院南京地理与湖泊研究所 生物统计与R运用 *
# Writen By Deng Jianming [email protected] *
# Wrote on 20160907 *
#*****************************************************