Raup Crick null model
raupcrick_nullmodel = function(spXsite,
reps = 999) {
## count number of sites and total species richness across all plots (gamma)
n_sites <- nrow(spXsite)
gamma <- ncol(spXsite)
##make the spXsite matrix into a new, pres/abs. matrix:
ceiling(spXsite / max(spXsite)) -> spXsite.inc
##create an occurrence vector- used to give more weight to widely distributed species in the null model:
occur <- apply(spXsite.inc, MARGIN = 2, FUN = sum)
##create an abundance vector- used to give more weight to abundant species in the second step of the null model:
abundance <- apply(spXsite, MARGIN = 2, FUN = sum)
##make_null:
nulllist <- NULL
for (i in 1:reps){
for (null.one in 1:nrow(spXsite)) {
##two empty null communities of size gamma:
com1 <- rep(0, gamma)
##add observed number of species to com1, weighting by species occurrence frequencies:
com1[sample(1:gamma,
sum(spXsite.inc[null.one, ]),
replace = FALSE,
prob = occur)] <- 1
com1.samp.sp = sample(which(com1 > 0),
(sum(spXsite[null.one, ]) - sum(com1)),
replace = TRUE,
prob = abundance[which(com1 > 0)])
com1.samp.sp = cbind(com1.samp.sp, 1)
# head(com1.samp.sp);
com1.sp.counts = as.data.frame(tapply(com1.samp.sp[, 2], com1.samp.sp[, 1], FUN = sum))
colnames(com1.sp.counts) = 'counts'
# head(com1.sp.counts);
com1.sp.counts$sp = as.numeric(rownames(com1.sp.counts))
# head(com1.sp.counts);
com1[com1.sp.counts$sp] = com1[com1.sp.counts$sp] + com1.sp.counts$counts
# com1;
#sum(com1) - sum(spXsite[null.one,]); ## this should be zero if everything work properly
rm('com1.samp.sp', 'com1.sp.counts')
spXsite[null.one,] <- com1
}
nulllist[[i]] <- spXsite
}
return(nulllist)
}
Prepare OTU table
library(vegan)
## Warning: 程辑包'vegan'是用R版本4.1.3 来建造的
## 载入需要的程辑包:permute
## Warning: 程辑包'permute'是用R版本4.1.3 来建造的
## 载入需要的程辑包:lattice
## This is vegan 2.5-7
#读取OTU表
otu_biom2 <- read.delim("./ncm/otu table.txt", row.names=1)
#查看样品序列条数
summary(colSums(otu_biom2))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 8565 16699 19754 20431 22386 36187
otu_biom2 = otu_biom2[,colSums(otu_biom2) > 8500]
#将OTU表转置为行名为样品名称,列名为OTU名称的表
otu<-t(otu_biom2)
head(rowSums(otu))
## t1 t2 t3 t4 t5 t6
## 22027 11132 28759 16766 17243 16677
#对OTU表进行抽平
otu = as.data.frame(rrarefy(otu, 8500))
head(rowSums(otu))
## t1 t2 t3 t4 t5 t6
## 8500 8500 8500 8500 8500 8500
#去除序列条数较少的OTU
otu2<-otu[,log(colSums(otu)/sum(otu),10)>-4.5]
#去除出现频率低的微生物,即去除只在少数样品中出现的OTU
otu_niche<-otu2[,colSums(otu2>0)/nrow(otu2)>0.2]
Generate null otu table
nullmodel <- raupcrick_nullmodel(otu_niche,4)
Correlation method
fast_spearman_fdr <- function(otu_niche){
r <- cor(otu_niche,method="spearman")
n = nrow(otu_niche)
t <- (r * sqrt(n - 2))/sqrt(1 - r^2)
p <- -2 * expm1(pt(abs(t), (n - 2), log.p = TRUE))
p[upper.tri(p, diag = FALSE)] <- p.adjust(p[upper.tri(p,diag = FALSE)], "fdr")
p[lower.tri(p, diag = FALSE)] = t(p)[lower.tri(p, diag = FALSE)]
return(list(r=r,p=p))
}
Network construction of simulated null otu table
cor <- fast_spearman_fdr(nullmodel[[2]])
## Warning in cor(otu_niche, method = "spearman"): 标准差为零
#cor <- fast_spearman_fdr(otu_niche)
corr <- cor$r
corr[is.na(corr)] = 0
corr[cor$r < 0.6] = 0
corr[cor$p > 0.05] = 0
library(igraph)
## Warning: 程辑包'igraph'是用R版本4.1.3 来建造的
##
## 载入程辑包:'igraph'
## The following object is masked from 'package:vegan':
##
## diversity
## The following object is masked from 'package:permute':
##
## permute
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
ng <- graph_from_adjacency_matrix(corr,mode="undirected",weighted=TRUE,diag = FALSE)
ng2 <- induced_subgraph(ng,colnames(corr)[colSums(corr)>1])
Network properties of null network
histogram(degree(ng2))

Network construction of observed otu table
cor <- fast_spearman_fdr(otu_niche)
#cor <- fast_spearman_fdr(otu_niche)
corr <- cor$r
corr[is.na(corr)] = 0
corr[cor$r < 0.6] = 0
corr[cor$p > 0.05] = 0
library(igraph)
ng <- graph_from_adjacency_matrix(corr,mode="undirected",weighted=TRUE,diag = FALSE)
ng2 <- induced_subgraph(ng,colnames(corr)[colSums(corr)>1])
Network properties of otu network
histogram(degree(ng2))
