#  IsoBoot version 3.2 BETA

### Bootstrap resampling analysis of stable isotope mixing models with 95% confidence intervals.
## Designed for Food Web Analysis. Inputs include trophic level and isotopic fractionation of consumers.
# (Copyright: R. Schwamborn, 2009)

# INSTRUCTIONS: 
# 1. Download and install "R" (www.r-project.org), then open this textfile in any editor. 
# 2. Write your data into "INPUT VALUES", copy the whole text and paste it into the "R" Console. 

### INPUT:
# M: mean isotopic signature for mixture (e.g. 13C of a consumer), 
# A: mean isotopic signature for source A (e.g. 13C of mangroves), 
# B:  mean isotopic signature for source B (e.g. 13C of algae), 
# sM: standard deviation of signatures from samples of M, 
# sA: standard deviation of signatures from samples of A, 
# sB: standard deviation of signatures from samples of B,

# nM: n of samples of mixture M,
# nA: n of samples of source A,
# nB: n of samples of source B,
# nF: n of samples used to calculate F,
### Note: unequal n allowed.

# TL: Trophic level of consumer M (TL = 2 for herbivores, 3 for carnivores, zero if unknown),
# F: Isotopic fractionation per trophic level (zero if unknown),
# sF: Standard deviation of F (zero if unknown),
# E: Measurement precision (zero or 0.3 if unknown),

# nMC:  Length of the original Monte Carlo simulation matrix (default: 20000 random numbers per variable), 
# NBoot: Number of bootstrap resampling runs (default: 999 runs).


### OUTPUT: 
# Percent contribution of source A consumer M.
# Upper and lower limits of the 95% confidence interval for this source contribution, based bootstrap resampling.
# Graph with the frequency distribution of the resampled contributions for source A.

### INPUT VALUES:

M <- (-25.54)
A <- (-28.42)
B <- (-20.63)
sM <- (1.19)
sA <- (1.03)
sB <- (1.19)

nM <- (3)      # n of samples for M
nA <- (3)      # n of samples for source A
nB <- (3)      # n of samples for source B

nF <- (2)      # n of samples used for F (default: 2)
TL <- (2)      # trophic level of M (default: 2)
F <- (0)     # Isotopic fractionation per TL (default: zero or 1.6)
sF <- (0)    # s.d.  of F (default: 0)
E <- (0.3)     # measurement precision (default: 0.3)

nMC <- (20000)  # Length of the original Monte Carlo simulation matrix.
NBoot <- (999)  # Number of bootstrap resampling runs.

### NOTES ###
# Note (nF): For nF, default is 2. Suggestion: use nF = 2 when F was obtained from a pair of single data, or n-1, when F was obtained from a regression of 13C vs TL.
# Note (E): It is not necessary to include a value for measurement precision E. Is is not used in the basic calculations, since it is implicit in the variability of the measured variables. E is used to check for the relative effects of sources of variability only.


### Calculations ###

# 1. General Mixing Function: Calculates Exact Contribution of Source A to Mixture M ("ContribA", zero to one):

# 1.a Defines the  mixing function.
mix.funA <- function(M, A, B)
{ contrib.A <- (M-B) / (A-B)
  contrib.A }
# Contribution of source A to mixture M, no correction for F:
mix.funA(M, A, B)
## [1] 0.6302953
# 1.b Correction for F and trophic level
# Equation for source A, considering F: 
mix.funFA <- function(M, A, B, F, TL)
{ contrib.A <- ((M +((-F) *(TL-1)))-B) / (A-B)
  contrib.A }
# Contribution of source A to mixture M, with correction for F:
mix.funFA(M, A, B, F, TL)
## [1] 0.6302953
# 2. Generates four Monte Carlo vectors with random numbers from original data, 
     # using  Mean and Standard Devs of samples.
     # length = 20,000 random numbers

M.vec <- rnorm(nMC, M, (sM))
A.vec <- rnorm(nMC, A, (sA))
B.vec <- rnorm(nMC, B, (sB))
F.vec <- rnorm(nMC, mean = F, sd = sF)

# hist(F.vec)

data.input <- data.frame(F.vec, M.vec, A.vec, B.vec)

#############

# 3. Resampling using the sample() function

## 3.a Define the sampling function

resample.fun <- function(d) { 

M.sample <- sample(d$M.vec, nM)
Mean.M.sample <- mean(M.sample)

A.sample <- sample(d$A.vec, nA)
Mean.A.sample <- mean(A.sample)

B.sample <- sample(d$B.vec, nB)
Mean.B.sample <- mean(B.sample)

F.sample <- sample(d$F.vec, nB)
Mean.F.sample <- mean(F.sample)

outp.sample.mat <- data.frame(Mean.M.sample, Mean.A.sample, Mean.B.sample, Mean.F.sample)
}

(subsample1 <-  resample.fun(data.input)) 
##   Mean.M.sample Mean.A.sample Mean.B.sample Mean.F.sample
## 1     -26.52027     -28.74843     -20.00138             0
#############

## 3.b Defines the function that generates a single value for ContribA from single averages for M, A, B, F

mix.funFA((subsample1$Mean.M.sample),(subsample1$Mean.A.sample),(subsample1$Mean.B.sample), (subsample1$Mean.F.sample), TL)  
## [1] 0.7452678
##############

## 3.c Construct a single function out of both, that takes n samples for each variable and generates a single value for ContribA from three means.

sample.and.calculate.fun <- function(d)

{

resample.and.mean.fun <- function(d) { 

M.sample <- sample(d$M.vec, nM)
Mean.M.sample <- mean(M.sample)

A.sample <- sample(d$A.vec, nA)
Mean.A.sample <- mean(A.sample)

B.sample <- sample(d$B.vec, nB)
Mean.B.sample <- mean(B.sample)

F.sample <- sample(d$F.vec, nB)
Mean.F.sample <- mean(F.sample)

outp.sample.mat <- data.frame(Mean.M.sample, Mean.A.sample, Mean.B.sample, Mean.F.sample)

}

## take samples, calculate means
subsample1 <-  resample.and.mean.fun(data.input)

## calculate a contribA value with this sample
mix.funFA((subsample1$Mean.M.sample),(subsample1$Mean.A.sample),(subsample1$Mean.B.sample), (subsample1$Mean.F.sample), TL)  

}


sample.and.calculate.fun(data.input)
## [1] 0.4807765
# 4. Resampling: Apply this function N times, taking n samples out of each column, using the initial normally distributed variables (n = 20000)

N.rep <- NBoot  # N of repaeted resamplings

outp.mat1 <- data.frame(c(1:(N.rep)),rep.int(0,(N.rep)))
names(outp.mat1) <- c("sample.no", "contribA")
summary(outp.mat1)
##    sample.no        contribA
##  Min.   :  1.0   Min.   :0  
##  1st Qu.:250.5   1st Qu.:0  
##  Median :500.0   Median :0  
##  Mean   :500.0   Mean   :0  
##  3rd Qu.:749.5   3rd Qu.:0  
##  Max.   :999.0   Max.   :0
for(line.no in 1:(N.rep)) {

outp.mat1$contribA[line.no] <- sample.and.calculate.fun(data.input) 

}

# 5. Outputs

## 5.a: Mean and Median of the resampling distribution
summary(outp.mat1)
##    sample.no        contribA     
##  Min.   :  1.0   Min.   :0.2880  
##  1st Qu.:250.5   1st Qu.:0.5517  
##  Median :500.0   Median :0.6292  
##  Mean   :500.0   Mean   :0.6296  
##  3rd Qu.:749.5   3rd Qu.:0.7077  
##  Max.   :999.0   Max.   :1.0109
mean(outp.mat1$contribA)
## [1] 0.6296151
median(outp.mat1$contribA)
## [1] 0.6291652
## 5.b: Makes a histogram of the Bootstrap Resampling Distribution
hist(outp.mat1$contribA, breaks = 50, main = "Bootstrap Resampling Distribution",
  sub = "lines: median and 95% quantiles", 
   xlab = "Mangrove Contribution (zero to 1)",
   xlim = c(0,1),
    axes = F )
axis(1, at = c(seq(0, 1, by = 0.1)))
abline(v = median(outp.mat1$contribA), lty = 3)
abline(v = quantile(outp.mat1$contribA, probs=c(.025)))
abline(v = quantile(outp.mat1$contribA, probs=c(.975)))

## 5.c: 95% Percentiles of resampling distribution - Approx. 95% Conf Int.
round(quantile(outp.mat1$contribA, probs=c(.025,0.975)), 2)
##  2.5% 97.5% 
##  0.42  0.85
#########################