我目前正在使用FD软件包中的FTD.Comm
函数对沿生态梯度的函数多样性进行量化。代码如下:
FTD<-function(tdmat,weights=NULL,q=1){
## contingency for one-species communities
if(length(tdmat)==1 && tdmat==0){
tdmat<-as.matrix(tdmat)
}
## is the input a matrix or dist? if not...
if(!(class(tdmat) %in% c("matrix","dist"))){
stop("distances must be class dist or class matrix")
} else if(class(tdmat)=="matrix" && !isSymmetric(unname(tdmat))){
warning("matrix not symmetric")
} else if(class(tdmat)=="dist"){
tdmat<-as.matrix(tdmat)
}
if(max(tdmat)>1 || min(tdmat)<0){
tdmat<-(tdmat-min(tdmat))/(max(tdmat)-min(tdmat))
warning("trait distances must be between 0 and 1; rescaling")
}
## if no weights are provided, abundances are assumed equal
if(is.null(weights)){
nsp<-nrow(tdmat)
weights<-rep(1/nsp,nsp)
} else {
nsp<-sum(weights>0)
}
if(identical(sum(weights),1)==F){
weights<-weights/sum(weights)
warning("input proportional abundances do not sum to 1; summation to 1
forced")
}
tdmat.abund<-diag(weights) %*% tdmat %*% diag(weights)
## Here, because sum(weights)=1, the sum is here already adjusted by dividing
by the
## square of the number of species (if weights=NULL)
## or by multiplying by proportional abundances (Rao's Q)
M<-sum(tdmat.abund)
M.prime<-M*nsp/(nsp-1)
fij<-tdmat.abund/M
## calculating qH
## fork -- if q=1, 1/(1-q) is undefined, so we use an analogue
## of the formula for Shannon-Weiner diversity
## if q!=1, we can calculate explicitly
if(q==1){
fijlog<-fij*log(fij)
fijlog[is.na(fijlog)]<-0
Ht<-exp(-1*sum(fijlog))
} else if(q==0){
Ht<-sum(fij>0)
} else {
Ht<-sum(fij^q)^(1/(1-q))
}
## getting qDT, qDTM, and Et from Ht
qDT<-(1+sqrt(1+4*Ht))/2
qDTM<-1+qDT*M
Et<-qDT/nsp
list(nsp=nsp,q=q,M=M,M.prime=M.prime,Ht=Ht,Et=Et,qDT=qDT,qDTM=qDTM)
}
## wrapper for the above function across multiple communities
## requires distance matrix w/ all species, scaled to 0-1
## community data matrix (communities x species)
## with species in same order as distance matrix
## if abund=T, values in community data matrix are treated as abundances
## otherwise, all are converted to presence-absence
## if match.names=T, the code will match species names across the
## trait distance matrix and comm data matrix and rearrange the latter
FTD.comm<-function(tdmat,spmat,q=1,abund=F,match.names=F){
if(abund==F){
spmat[spmat>0]<- 1
spmat<-spmat/rowSums(spmat)
}
n.comm<-nrow(spmat)
if(match.names==T){
sp.arr<-match(rownames(as.matrix(tdmat)),colnames(spmat))
spmat<-spmat[,sp.arr]
}
## apply FTD to each community in turn
out<-apply(spmat,1,function(x) unlist(FTD(tdmat=tdmat,weights=x,q=q)))
df.out<-data.frame(t(out))
rownames(df.out)<-rownames(spmat)
## warning for zero-species communities
if(sum(df.out$nsp==0)>0){
warning("at least one community has no species")
}
nsp<-sum(colSums(spmat>0))
## calculate mean richness, dispersion, evenness, FTD
u.M<-sum(df.out$nsp*df.out$M)/sum(df.out$nsp)
u.nsp<-mean(df.out$nsp)
## to do: check if u.nsp is always calculated as arithmetic mean
if(q==1){
## geometric mean -- limit of generalized mean as q->1
u.qDT<-prod(df.out$qDT)^(1/n.comm)
} else {
## generalized mean with m=1-q
u.qDT<-(sum(df.out$qDT^(1-q))/n.comm)^(1/(1-q))
}
u.M.prime<-u.M*u.nsp/(u.nsp-1)
## calculate mean FTD and evenness
u.qDTM<-1+u.qDT*u.M
u.Et<-u.qDT/u.nsp
## list more things
list(com.FTD=df.out,nsp=nsp,u.nsp=u.nsp,u.M=u.M,u.M.prime=u.M.prime,u.Et=u.Et,u.q DT=u.qDT,u.qDTM=u.qDTM)
}
FTD.dat <- FTD.comm(tdmat,spmat)
FTD.dat
该代码可以完美地工作,并可以量化我站点之间的功能特征分布。但是,我似乎无法使用picante
软件包将此功能成功地应用于null模型。这是我尝试使用此功能进行试验交换空模型的最小可复制示例:
library(base)
library(FD)
library(picante)
traits <- read.table("Practice_trait_data.txt", header = T, row.names = 1)
tdmat <- gowdis(traits)
my.matrix <- read.table("PRACTICE_COMMUNITY_MATRIX.txt", header = T, row.names = 1)
spmat <- data.matrix(my.matrix)
FTD.null <- function(tdmat, spmat) { FTD.comm((randomizeMatrix(spmat, null.model = "trialswap", iterations = 1000)), tdmat) }
obs.null.output <- cbind(FTD.comm(tdmat,spmat), replicate(999, FTD.null(tdmat)))
运行obs.null.output
行之后,我收到错误消息:Error in rowSums(spmat) : 'x' must be an array of at least two dimensions.
R中的Swenson功能生态学书中推荐使用此方法。开发人员向我保证,他已经在picante软件包中使用了此功能,因此必须有一种方法可以在999个随机生成的矩阵中应用此功能。此功能已在我的实际数据和组合数据集上进行了测试。所有数据在各个站点的存在/不存在(0,1)格式,并不表示数量过多。
谢谢您的协助 问候 尼克尔(Nikhail)