jbi12503-sup-0003-AppendixS3

advertisement
Journal of Biogeography
SUPPORTING INFORMATION
Climatic drivers of trait assembly in woody plants in Japan
Takayuki Shiono, Buntarou Kusumoto, Ryo Maeshiro, Shin-jiro Fujii, Lars Götzenberger,
Francesco de Bello and Yasuhiro Kubota
Appendix S3 R code for calculating standardized effect sizes of the functional structure
indices by using three null models. For null model 1, the null distributions were generated by
sampling the grid cell-specific number of species without replacement from the pool of all
773 species in the Japanese archipelago. This null model and sampling scheme standardized
the value of the functional trait structure indices by removing the sampling effect that results
from differences in the number of species in the grid cells. For null model 2, the null
distributions were generated by randomization of the grid cell–species matrix while keeping
the number of species in the grid cells and the frequency of species occurrence across the grid
cells using a quasi-swap algorithm. This scheme removed the sampling effects of species in
the grid cells while considering the geographical coverage of each species: common (or rare)
species remained common (or rare). For null model 3, we considered the influence of
historical dispersal limitation as a result of geographical vicariance on the regional species
pools. The Japanese archipelago represents a transitional region between the Palaeotropical
(Indo-Pacific) and Holarctic kingdoms, and it is divided into three biogeographical regions by
the Tsugaru Strait and the Tokara Strait (Fig. 1): the northern, central and southern regions.
Therefore, the current species distribution was affected by historical dispersal limitations at a
biogeographical scale and, as a consequence, the species pool differs among the three
regions: certain species are absent from a given regional species pool as a result of vicariance,
not because they could not survive under the current climatic conditions in that region. Such
biogeographical features might invalidate the creation of a simple null sample that assumes a
single species pool across the Japanese archipelago. To overcome this problem, we conducted
an analysis with null model 3 that assumed three species pools (north, centre and south) in
which only species that were distributed in each biogeographical region were defined as
candidate community members of the grid cells that we surveyed. The null distributions of
null model 3 were generated by sampling the grid cell-specific number of species without
replacement from the each species pool.
#####################################################################
# Packages
#####################################################################
library( ade4 )
library( vegan )
library( geometry )
#####################################################################
# Sample data
#####################################################################
## These sample data are just for checking the code.
## Nonetheless, the fundamental structures of the sample data are the same as those of the
original data.
# Species pools------------------------------------------------------## We defined species pools in two ways, i.e. overall and regional pools,
## to obtain the null distributions of functional structure indices.
#Overall
## All 15 species contained in dataset.
Spool_all
<c( "spA","spB","spC","spD","spE","spF","spG","spH","spI","spJ",
"spK","spL","spM","spN","spO" )
## Regional species pools in the Japanese archipelago, divided into three regions:
'North', 'Centre', 'South'
## In the manuscript, these were defined based on the locations of grid cells and
geographical ranges of each species.
#Regional pool1: North
Spool_r1
<- c( "spA","spB","spC","spD","spE" )
#Regional pool2: Centre
Spool_r2
<c( "spC","spD","spE","spF","spG","spH","spI","spJ","spK","spL" )
#Regional pool3: South
Spool_r3
<- c( "spH","spI","spJ","spK","spL","spM","spN","spO" )
# Species presence/absence matrix (places x species)-----------------## In this supplemental code, we assumed nine grid cells with 15 species.
spa.vec <- c(
0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,
1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,
0,0,1,1,1,1,0,0,1,0,0,1,0,0,0,
0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,
0,0,0,1,1,1,0,1,0,1,0,1,0,0,0,
0,0,0,0,0,0,0,0,1,0,1,0,1,1,1,
0,0,0,0,0,0,0,0,1,1,0,1,0,1,1,
0,0,0,0,0,0,0,1,1,1,0,1,0,0,1 )
Sp_matrix
<- matrix( spa.vec, nrow = 9, ncol = 15, dimnames = list(1:9,
Spool_all), byrow = TRUE )
#Species functional trait matrix (species x traits) ------------------SLA
<- c( 7.4, 13.4, 38.9, 14.8, 20.0, 23.1, 18.4, 16.3, 14.2, 10.2, 17.7, 15.7, 9.0,
6.0, 11.4 )
WD
<- c( 0.55, 0.46, 0.47, 0.50, 0.57, 0.55, 0.56, 0.53, 0.52, 0.49, 0.28, 0.31,
0.65, 0.44, 0.59 )
Trait_matrix
<- cbind( SLA, WD )
rownames( Trait_matrix ) <- Spool_all
#####################################################################
# Function to calculate functional structure index
#####################################################################
## We defined the function to calculate each functional structure indices.
## Input data are as follows.
## spm : species presence/absence matrix
## trm : trait matrix
## trait : name(s) of a focal trait
# Community mean (CM)------------------------------------------------calc.cm <- function( spm, trm, trait ){
res
<- NULL
for( i in 1:length(trait) ){
trait_tab <- t( t(spm) * trm[colnames(spm),
trait[i]] )
res.i
<- apply( trait_tab, 1, function(x)
mean(x[x != 0]) )
res
<- cbind( res, res.i )
}
dimnames( res )[[2]]
<- trait
return( res )
}
# Functional richness (FRic)-----------------------------------------calc.ric <- function( spm, trm, trait ){
if( length(trait) < 2 ){
rtrait_tab
<- t( t(spm) *
c(scale(trm[colnames(spm), trait])) )
res
<- apply( rtrait_tab, 1, function(x)
range(x[x != 0])[2] - range(x[x != 0])[1] )
}
if( length(trait) >= 2 ){
res
<- NULL
for( i in 1:nrow(spm) ){
trm2
<- apply( trm, 2, function(x)
scale(x) * spm[i, ] )
convhull<- convhulln( trm2, options =
"FA" )
res
<- c( res, convhull$vol )
}
}
return( res )
}
# Functional divergence (RaoQ)---------------------------------------## This function will return RaoQ values with warning messages if a grid cell contains some
species having equivalent trait values as one another.
calc.rao <- function( spm, trm, trait ){
tr.dist <- dist( scale(trm[colnames(spm), trait]) )
res
<- unlist( divc(data.frame(t(spm), check.names =
FALSE), tr.dist, scale=FALSE) )
names( res )
<- rownames( spm )
return( res )
}
#####################################################################
# Calculation of functional structure index by using observed data
#####################################################################
## Observed values of functional structure indices for single traits were calculated.
TRAIT <- c("WD","SLA") #chose focal trait
CM.obs <- calc.cm( Sp_matrix, Trait_matrix, TRAIT )
FRic.obs
<- calc.ric( Sp_matrix, Trait_matrix, TRAIT )
RaoQ.obs
<- calc.rao( Sp_matrix, Trait_matrix, TRAIT )
#####################################################################
# Calculation of functional structure index by using null models
#####################################################################
## Simulated values of functional structure indices for single traits were calculated using
three null models.
Ncom
<- nrow( Sp_matrix ) #Number of grid-cells
Nsp
<- apply( Sp_matrix, 1, sum )
N
<- 100 #times of iteration
#Number of species in each grid-cell
# Null model1: overall model-----------------------------------------## Sampling the grid cell-specific number of species without replacement from the overall
species pool by keeping the species number in each grid cell.
CM.sim_n1
<- array( NA, dim = c(Ncom, length(TRAIT), N), dimnames =
list(rownames(Sp_matrix), TRAIT, 1:N) )
FRic.sim_n1
<- NULL
RaoQ.sim_n1 <- NULL
for( i in 1:N ){
sim.mat <- matrix( NA, nrow = Ncom, ncol = ncol(Sp_matrix), dimnames =
dimnames(Sp_matrix) )
for( j in 1:Ncom ){
rsmp <- sample( Spool_all, Nsp[j] )
sim.mat[ j, ]<- as.numeric( colnames(sim.mat) %in% rsmp )
}
cm.sim <- calc.cm( sim.mat, Trait_matrix, TRAIT )
fr.sim <- calc.ric( sim.mat, Trait_matrix, TRAIT )
rao.sim <- calc.rao( sim.mat, Trait_matrix, TRAIT )
CM.sim_n1[ , , i ]
<- cm.sim
FRic.sim_n1
<- rbind( FRic.sim_n1, fr.sim )
RaoQ.sim_n1 <- rbind( RaoQ.sim_n1, rao.sim )
}
# Null model2: fixed to fixed model----------------------------------------## Randomizing presence/absence matrix by keeping margins (the number of species in the
grid cells and
## the frequency of species occurrence across the grid cells) using a quasi-swap algorithm.
CM.sim_n2
<- array( NA, dim = c(Ncom, length(TRAIT), N), dimnames =
list(rownames(Sp_matrix), TRAIT, 1:N ) )
FRic.sim_n2
<- NULL
RaoQ.sim_n2 <- NULL
for( i in 1:N ){
sim.mat
cm.sim
fr.sim
rao.sim
<- commsimulator( Sp_matrix, method="quasiswap" )
<- calc.cm( sim.mat, Trait_matrix, TRAIT )
<- calc.ric( sim.mat, Trait_matrix, TRAIT )
<- calc.rao( sim.mat, Trait_matrix, TRAIT )
CM.sim_n2[ , , i ]
<- cm.sim
FRic.sim_n2
<- rbind( FRic.sim_n2, fr.sim )
RaoQ.sim_n2 <- rbind( RaoQ.sim_n2, rao.sim )
}
# Null model3: dispersal limited model-------------------------------------## Sampling the grid cell-specific number of species without replacement from each of the
three species pools.
## In this example of the supplemental code, we defined the relationship between grid cells
and regional species pools as follows: North = { 1, 2, 3 }; Centre = { 4, 5, 6 }; South = { 7, 8,
9}
CM.sim_n3
<- array( NA, dim = c(Ncom, length(TRAIT), N), dimnames =
list(rownames(Sp_matrix), TRAIT, 1:N) )
FRic.sim_n3
<- NULL
RaoQ.sim_n3 <- NULL
region <rep( c("North", "Centre", "South"), rep(3, 3) )
for( i in 1:N ){
sim.mat <- matrix( NA, nrow = Ncom, ncol = ncol(Sp_matrix), dimnames =
dimnames(Sp_matrix) )
for( j in 1:Ncom ){
switch( region[j],
"North" =
rsmp
<- sample( Spool_r1, Nsp[j] ),
"Centre" =
rsmp
<- sample( Spool_r2, Nsp[j] ),
"South" =
rsmp
<- sample( Spool_r3, Nsp[j] )
)
sim.mat[ j, ]<- as.numeric( colnames(sim.mat) %in% rsmp )
}
cm.sim <- calc.cm( sim.mat, Trait_matrix, TRAIT )
fr.sim <- calc.ric( sim.mat, Trait_matrix, TRAIT )
rao.sim <- calc.rao( sim.mat, Trait_matrix, TRAIT )
CM.sim_n3[ , , i ]
<- cm.sim
FRic.sim_n3
<- rbind( FRic.sim_n3, fr.sim )
RaoQ.sim_n3 <- rbind( RaoQ.sim_n3, rao.sim )
}
#####################################################################
#Calculation of standard effect size (SES) of functional structure indices
#####################################################################
## SES values of each index were calculated for each grid cell as (the observed value - the
mean of the null distribution)/the standard deviation of the null distribution.
# SES_null1----------------------------------------------------------#mean & SD of simulated values
cm_sim.m_n1 <- apply( CM.sim_n1, c(1, 2), mean )
cm_sim.SD_n1 <- apply( CM.sim_n1, c(1, 2), sd )
fr_sim.m_n1
fr_sim.SD_n1
<- apply( FRic.sim_n1, 2, mean )
<- apply( FRic.sim_n1, 2, sd )
rao_sim.m_n1 <- apply( RaoQ.sim_n1, 2, mean )
rao_sim.SD_n1 <- apply( RaoQ.sim_n1, 2, sd )
#SES
SES.CM_n1
SES.FRic_n1
SES.RaoQ_n1
<- ( CM.obs - cm_sim.m_n1 ) / cm_sim.SD_n1
<- ( FRic.obs - fr_sim.m_n1 ) / fr_sim.SD_n1
<- ( RaoQ.obs - rao_sim.m_n1 ) / rao_sim.SD_n1
# SES_null2----------------------------------------------------------#mean & SD of simulated values
cm_sim.m_n2 <- apply( CM.sim_n2, c(1, 2), mean )
cm_sim.SD_n2 <- apply( CM.sim_n2, c(1, 2), sd )
fr_sim.m_n2
fr_sim.SD_n2
<- apply( FRic.sim_n2, 2, mean )
<- apply( FRic.sim_n2, 2, sd )
rao_sim.m_n2 <- apply( RaoQ.sim_n2, 2, mean )
rao_sim.SD_n2 <- apply( RaoQ.sim_n2, 2, sd )
#SES
SES.CM_n2
SES.FRic_n2
SES.RaoQ_n2
<- ( CM.obs - cm_sim.m_n2 ) / cm_sim.SD_n2
<- ( FRic.obs - fr_sim.m_n2 ) / fr_sim.SD_n2
<- ( RaoQ.obs - rao_sim.m_n2 ) / rao_sim.SD_n2
# SES_null3----------------------------------------------------------#mean & SD of simulated values
cm_sim.m_n3 <- apply( CM.sim_n3, c(1, 2), mean )
cm_sim.SD_n3 <- apply( CM.sim_n3, c(1, 2), sd )
fr_sim.m_n3
fr_sim.SD_n3
<- apply( FRic.sim_n3, 2, mean )
<- apply( FRic.sim_n3, 2, sd )
rao_sim.m_n3 <- apply( RaoQ.sim_n3, 2, mean )
rao_sim.SD_n3 <- apply( RaoQ.sim_n3, 2, sd )
#SES
SES.CM_n3
SES.FRic_n3
SES.RaoQ_n3
<- ( CM.obs - cm_sim.m_n3 ) / cm_sim.SD_n3
<- ( FRic.obs - fr_sim.m_n3 ) / fr_sim.SD_n3
<- ( RaoQ.obs - rao_sim.m_n3 ) / rao_sim.SD_n3
Download