Topic: Growth

Topic Description:

Functions for analyzing tree growth, designed for the standard CTFS R Analytical Tables.



File: growth/growth.r

View File Source Download File No help file available

Function: growth

Function Description: growth

The principle growth function, constructed like recruitment and mortality. It requires two complete datasets, one per census, with dbh, pom, and date for every individual of all species in at least 2 censuses (see Data Format). It calculates the mean growth rate in one or more categories defined by the split variables, split1 and split2. The column date is required for annualizing rates. The columns status and stemID are both required, in order to determine which stems should have dbh change calculated. The function trim.growth handles all checks for trees to include; excluded are cases where the stemID changes, extreme values based on err.limit and maxgrow, and trees below a minimum dbh in the first census. See the description of trim.growth for more information. Growth requires fill.dimension in utilities.r.

Output of the growth function is a list with components:
  • rate, the mean annualized growth rate per category selected, either dbh increment, or relative growth
  • N, the number of individuals included in the mean (not counting any excluded)
  • clim, width of confidence interval; add this number to the mean rate to get upper confidence limit, substract to get lower
  • dbhmean, mean dbh in census 1 of individuals included
  • time, mean time interval in years
  • date1, mean date included individuals were measured in census 1, as julian object (R displays as date, but treats as integer)
  • date2, mean date in census 2
Pass the list to assemble.demography (in utilities.r) with type="g" to convert the list to a data.frame.

Function Arguments:

ArgumentDefault Value
census1
census2
rounddownFALSE
method'I'
stdevFALSE
dbhunit'mm'
mindbh10
growthcol"dbh"
err.limit4
maxgrow75
split1NULL
split2NULL

Arguments Description:

  • Usually use rounddown=FALSE; if TRUE, all dbh<55 are rounded down to the nearest multiple of 5
  • With method='I', annual dbh increment is calculated, (dbh2-dbh1)/time; with method='E', relative growth rate, (log(dbh2)-log(dbh1))/time
  • With stdev=FALSE, confidence limits are returned, otherwise the SD in growth rate per group
  • dbhunit must be 'mm' or 'cm'
  • mindbh is the minimum dbh to include in results
  • growthcol defines how growth is measured, either 'dbh' or 'agb' (agb=biomass)
  • for err.limit and maxgrow, see trim.growth()
  • split1 and split2 must both be vectors of character variables with exactly as many elements as there are rows in the tables census1 and census2 (or both can be NULL), for instance, species names, dbh categories, or quadrat numbers


Sample Usage:

CTFSplot("bci",5:6)
growth.data=growth(bci.full5,bci.full6)
growth.data$rate
growth.data=growth(bci.full5,bci.full6,split1=bci.full5$sp)
growth.data$rate
assemble.demography(grow.data,type='g')


Function Source:


growth=function(census1,census2,rounddown=FALSE,method='I',stdev=FALSE,dbhunit='mm',mindbh=10,growth
        col="dbh", err.limit=4,maxgrow=75,split1=NULL,split2=NULL)
{
size1=census1[,growthcol]
size2=census2[,growthcol]

if(is.null(split1)) split1=rep('all',dim(census1)[1])
if(is.null(split2)) split2=rep('all',dim(census2)[1])

if(is.null(census2$codes)) census2$codes=rep('.',length(size2))

time=(census2$date-census1$date)/365.25

if(rounddown)
{
sm=((size1<55 | size2<55) & !is.na(size1) & !is.na(size2))
size1[sm]=rndown5(size1[sm])
size2[sm]=rndown5(size2[sm])
}

if(method=='I') growthrate=(size2-size1)/time
else if(method=='E') growthrate=(log(size2)-log(size1))/time
good=trim.growth(census1,census2,time,err.limit=err.limit,maxgrow=maxgrow,mindbh=mindbh)
growthrate[!good]=NA

class1=sort(unique(split1))
class2=sort(unique(split2))
splitgood=list(split1[good],split2[good])

mean.grow=tapply(growthrate[good],splitgood,mean,na.rm=TRUE)
sd.grow=tapply(growthrate[good],splitgood,sd,na.rm=TRUE)
N=tapply(growthrate[good],splitgood,length)
meandbh=tapply(census1$dbh[good],splitgood,mean,na.rm=TRUE)
meansize=tapply(size1[good],splitgood,mean,na.rm=TRUE)
interval=tapply(time[good],splitgood,mean,na.rm=TRUE)
startdate=tapply(census1$date[good],splitgood,mean,na.rm=TRUE)
enddate=tapply(census2$date[good],splitgood,mean,na.rm=TRUE)

mean.grow=fill.dimension(mean.grow,class1,class2,fill=NA)
sd.grow=fill.dimension(sd.grow,class1,class2,fill=NA)
N=fill.dimension(N,class1,class2,fill=0)
meandbh=fill.dimension(meandbh,class1,class2,fill=NA)
interval=fill.dimension(interval,class1,class2,fill=NA)
startdate=fill.dimension(startdate,class1,class2,fill=NA)
enddate=fill.dimension(enddate,class1,class2,fill=NA)

ci.grow=sd.grow
ci.grow[N==0]=NA
ci.grow[N>0]=sd.grow[N>0]*qt(0.975,N[N>0])/sqrt(N[N>0])

# ord=order(drp(meandbh))
if(!stdev)
result=list(rate=drp(mean.grow),N=drp(N),clim=drp(ci.grow),dbhmean=drp(meandbh),
time=drp(interval),date1=drp(startdate),date2=drp(enddate))
else
result=list(rate=drp(mean.grow),N=drp(N),sd=drp(sd.grow),dbhmean=drp(meandbh),
time=drp(interval),date1=drp(startdate),date2=drp(enddate))

return(result)
}