source('treeCorFunctions.r')
cols <- c("#3288BD", "#D53E4F", "#a65628")
blueGreen <- colorRampPalette( c('#67a9cf','#3690c0','#02818a','#016450') )This set of algorithms determines tree-to-tree correlation in growth and fecundity, and it summarizes correlations by conspecific and heterospecific pairs of individuals. For fecundity, it extracts annual estimates from trees on MASTIF sites. For diameter growth, it uses raw diameter data from MASTIF and other sites with repeated censuses. For fecundity, only seed-producing individuals are included. For growth, comparisons are restricted to individuals with a minimal number of overlapping measurements.
After loading census data in the MASTIF format treeData
(tree-years by variables), the function minCensus extracts
trees that have been measured at least minCens times. In
the MASTIF format, locations are held in a separate
data.frame xytree. Locations are concatenated to
treeData in the column minCensus.
If minCens is too small, say 3 measurements, there will
be many trees, but pairwise correlations will be poorly
supported–results will be noisy. If minCens is too large,
few trees will qualify, and the distribution of pairwise correlations
will contain few values. The value for minCens has to
balance these concerns. Diameter growth needs at least 4 censuses.
Fecundity needs at least 3 censuses.
minCensus( tdata, xy, minCens = 4 )
# tdata - tree-years by variables, including plot, tree, year, diam
# xy - trees by variables, including plot, tree, x, y
# minCens - at least 4 needed for growth, three for fecundityCompetition is local, so we need to approximate a tree’s
neighborhood. The inventory plot is partitioned into neighborhoods of
area wide^2. Each tree is assigned to one neighborhood or
tile. The function getTile appends a column to
treeData with an integer value for the competition
neighborhood.
getTile( tdata, wide = 40 )
# tdata - tree-years by variables, including plot, tree, year, diam, x, y
# wide - wide of tile (m)Correlations are compiled for individuals having i) overlappling
sample histories of measurement of at least minCens years
and ii) are within the same neighborhood (tile). The
function treeCor takes data for one neighborhood and
compiles the individual pairwise correlations as a matrix. For growth,
it returns this matrix with NA values for pairs that do not
have the same measurement history. Diameter measurements (cm) are
transformed into growth (cm/yr) prior to correlation. For fecundity, it
removes individuals that are not reproductive.
treeCor( tdata, varName = 'diam', minCens = 4 )
# tdata - tree-years by variables for one tile, including treeID, year, species, diam, x, y,
# and varName, which can be 'diam' or 'fecEstMu' (fecundity)The function treeCor returns several objects:
| Object | Structure | variables |
|---|---|---|
| tileData | tile by variables | mean intra/inter cor, n, richness, diversity, density |
| corTile | spp by spp | mean pairwise correlation |
| covTile | spp by spp | mean pairwise covariance |
| ncomp | spp by spp | no. of pairwise comparisons |
| xmu | tile by spp | mean response (‘diam’ or ‘fecEstMu’) |
| xvar | tile by spp | variance of response |
| ntree | by spp | no. trees |
The function tileCorrelation takes the
data.frame treeData, which includes the tile
column, and returns a summary matrix of correlation data.
The rows are tile numbers. The columns include the mean intra- and
inter-specific correlations for that tile
('intraMu', 'interMu') and the 90% interval
('intra05', 'intra95', 'inter05', 'inter95').
tileCorrelation( tdata, wide, varName = 'diam', FULLCOR = F ){
# tdata requires a tile column, 1, 2, ...
# returns:
# corMat - tile by mean pairwise correlation differences
# covMatrix - species by species mean covariances (not a covariance matrix)
# growth - mean species growthHere is an example for diameter growth for BCI data.
load( 'treeData_diam/BCI.rdata', verbose = T )
wide <- 30
treeData <- minCensus( treeData, xytree, minCens = 4 )
treeData <- getTile( treeData, wide = wide )
bciCor <- tileCorrelation( treeData, wide = wide, varName = 'diam' )
tileData <- bciCor$tileData
covMatrix <- bciCor$covMatrix
corMatrix <- bciCor$corMatrix
comMatrix <- bciCor$comMatrix
xmu <- bciCor$xmu
xse <- bciCor$xse
ntree <- bciCor$ntreeHere is the tiled stem map for BCI:
par( bty='n')
plot( treeData$x, treeData$y, cex = treeData$diam/200,
col = blueGreen(5)[ 2*(1 + treeData$tile %% 2) ],
asp = 1, xlab = '', ylab = '')
Thirty-meter tiles for BCI. Correlations between trees are evaluated at
this scale, defined by parameter wide.
The function tileCorrelation returns several
objects:
| Object | Structure | variables |
|---|---|---|
| tileData | tile by variables | mean intra/inter correlation, n, richness, diversity, density |
| corMatrix | spp by spp | mean pairwise correlation |
| covMatrix | spp by spp | mean pairwise covariance |
| comMatrix | spp by spp | no. of pairwise comparisons |
| xmu | tile by spp | mean response (‘diam’ or ‘fecEstMu’) |
| xse | tile by spp | SE of response |
| ntree | tile by spp | no. of trees |
The value NA is used where there are insufficient
comparisons.
This code gives the proportionate fractional dominance
library( corrplot )
corMatrix[ !is.finite(corMatrix) ] <- 0
covMatrix[ !is.finite(covMatrix) ] <- 0
corrplot( t(corMatrix), is.corr = T, type = 'lower', order = 'hclust', tl.pos = 'n',
addgrid.col = NA)The differences in scale for species makes the covariance matrix hard to plot (most values are white). Here is the matrix of correlations:
Mean pairwise correlations for BCI growth data, with high values (blue) clustered along the diagonal.
This code plots histograms:
par( mfrow=c(1,2), bty='n', omi = c(.2, .1, .1, .1) )
corHist( tileData[,2], ylab = 'Frequency', col = cols[2] )
corHist( tileData[,1], add = T )
legend( 'topright', c('intra','inter'), text.col = cols, bty='n')
title( 'a) Pairwise correlations', font.main = 6 )
corHist( tileData[,1] - tileData[,2], col = 'white', xlim = c(-.05, .2), ylim = c(0, 6) )
abline( v = 0, col = 'white', lwd=3)
abline( v = 0, lty=2, col = 'grey', lwd=3)
corHist( tileData[,1] - tileData[,2], col = cols[3], add = T )
title( 'b) Intra- minus inter-specific', font.main = 6 )
mtext('Correlation', 1, outer=T, line = -1.5, cex = 1.2)Below are histograms for mean correlations between individuals of the same and different species within a neighborhood (tile) at BCI. At right is the histogram of correlation differences.
Histograms of mean tile correlations between tree growth rates for intra- and inter-specific comparisons (left) with their difference (right) for BCI.
The next block uses the function getData to merge sites
by biome. To change this grouping edit your version of the function
groupSites( sites ) in the file
treeCorFunctions.R. Here are comparisons for diameter data
from multiple sites:
wide <- 30
varName <- 'diam'
minCens <- 4
minDiam <- 5
tmp <- getData( varName, wide, minCens, minDiam = minDiam )
tileList <- tmp$tileList
corList <- tmp$corList
covList <- tmp$covList
comList <- tmp$comList
xmu <- tmp$xmu
xse <- tmp$xse
tileList <- tileList[ sapply(tileList, nrow) > 10 ]
dlim <- c(-.2, 1)
breaks <- seq( -1.5, 1.5, by = .05 )
words <- plotSetup(names(tileList))
np <- nrow(words)
xlabels <- ylabels <- F
for( j in 1:np){
ylabels <- F
yaxt <- 'n'
if( j == 1 ){
ylabels <- T
yaxt <- 's'
}
tmp <- mergeCov( tileList[j], covList[j], corList[j], comList[j], cint = .04 )
x <- tmp$density
tl <- tmp$tileList
st <- tmp$stats
corHist( tl[,2], col = cols[2], xlim = dlim, ylim = c(0, 3),
breaks = breaks, xaxt = 'n', yaxt = yaxt )
corHist( tl[,1], col = cols[1], breaks = breaks, add = T )
title( words[j,1], font.main= 6, line = -.5, cex=.9 )
title( words[j,2], font.main= 6, line = -1.5, cex=.9 )
if( j == np )legend( 'right', c('intra','inter'), text.col = cols, bty='n')
corHist( tl[,1] - tl[,2], col = 'white', xlim = dlim, ylim = c(0, 3),
breaks = breaks, xaxt = 'n', yaxt = yaxt )
abline( v = 0, col = 'white', lwd=3)
abline( v = 0, lty=2, col = 'grey', lwd=3)
corHist( tl[,1] - tl[,2], col = cols[3], breaks = breaks, add = T )
ylim <- c(.1,100)
dif <- tl[,1] - tl[,2]
wf <- which( is.finite(dif) )
plot( dif, tl[,'BA'], xaxt = 'n', ylim = ylim, yaxt = 'n',
xlab = '', ylab = '', xlim = dlim, log = 'y', cex=.8,
pch = 16, col = .getColor( cols[3], .4) )
axis( 2, labels = ylabels)
axis( 1, labels = F )
abline( v = 0, lwd = 3, col = 'white' )
abline( v = 0, lwd = 3, lty = 2, col = 'grey' )
if( length(wf) > 5 )reg2plot( dif, tl[,'BA'], col = cols[1], p = .1, ylim = ylim )
ylim <- c(.5,5)
plot( dif, tl[,'diversity'], xaxt = 'n', yaxt = 'n',
xlab = '', ylab = '', ylim = ylim, log = 'y', xlim = dlim, cex=.8,
pch = 16, col = .getColor( cols[3], .3) )
axis( 2, labels = ylabels)
axis( 1, labels = T )
abline( v = 0, lwd = 3, col = 'white' )
abline( v = 0, lwd = 3, lty = 2, col = 'grey' )
if( length(wf) > 5 )reg2plot( dif, tl[,'diversity'], col = cols[1], p = .1, ylim = ylim )
}
mtext( paste0( c( 'Diversity', 'BA (m2/ha)', 'Cor Difference', 'Correlation' ),
collapse = ' '), 2, outer=T, line = 1 )
mtext( 'Correlation', 1, outer = T, line = 3 )Intra- and inter-specific comparisons (first row) for diameter growth, with the difference histogram (2nd row). The two rows at bottom plot the correlation difference against the tile density and diversity (Shannon entropy).
Same as above with wide = 50 m.
Intra- and inter-specific comparisons (first row) for fecundity, with the difference histogram (2nd row). The two rows at bottom plot the correlation difference against the tile density and diversity (Shannon entropy).
Mean correlation difference by site for diameter growth.
Fecundity estimates from MASTIF can be evaluated using the same code.
In the previous block, I change varName <- fecEstMu, and
minCens <- 3. Here are plots:
Intra- and inter-specific comparisons (first row) for fecundity, with the difference histogram (2nd row). The two rows at bottom plot the correlation difference against the tile density and diversity (Shannon entropy).
Same as previous with wide = 50 m.
Mean correlation difference by site for fecundity.