##########################################################
###### FUNCIONES IM(), EDAD(), GRUPO_EDAD() y ab() #######
##########################################################

# Libraries
##########################################################
library(egg)
library(gdata)
library(dplyr)
library(tidyr)
library(FSA) 
library(utils)
##########################################################

# PREAMBULO
##########################################################
# Delete all objets of workspace
rm(list=ls(all=TRUE))
options(digits = 9, scipen=999)
set.seed(1234)
##########################################################

Marginal increment

As a rule, if the marginal increment is translucent it is not counted because it is not fully formed. in the for cycle above, we calculate the proportion of the traslucent increment i in relation of the inncrement i-1.

IM <- function(x){
  
  im <- rep(NA, length(auxAge2$RADIO_TOTAL))
  rt <- auxAge2$RADIO_TOTAL 
  df <- auxAge2
  
  for(i in 1:dim(df)[1]){
    
    RT <- numeric(); RT = rt[i]
    temp <- numeric(); temp = df[i,c(9:32)] 
    
    if(all(is.na(as.numeric(temp))))
      
      im[i] <- 0.249
    
    else
      
      X1 = numeric(); X1 = temp[which(is.na(as.numeric(temp)))[1]-2]
      X2 = numeric(); X2 = temp[which(is.na(as.numeric(temp)))[1]-1]
    
    if(length(X1) > 0 & length(X2) > 0)
      
      if(as.numeric(X1) > 0 & as.numeric(X2) > 0)
        
        im[i] <- (RT-as.numeric(X2))/(as.numeric(X2)-as.numeric(X1))
    
    else
      
      im[i] <- 0.249
      
    else
      
      im[i] <- 0.249 
    
  }
  
  im[which(im > 1)] <- 0.249
  im[which(im <= 0)] <- 0.249
  
  return(im) 
  
}  

Age

To estimate the biological age, the number of radii recorded and the nature of the otolith edge are considered. If the otolith edge is hyaline (values 3 or 4 of the variable BORDE), one is added to the number of radii counted.

EDAD <- function(x,y){
  
  z <- numeric(length = length(x))
  
  for(i in 1:length(x)){

    if(y[i] > 2) 
      
      z[i] <- x[i] + 1
    
    else 
      
      z[i] <- x[i]
  }
  
  return(z)
  
}

Age group

The age group is the number of calendar years after the date of capture, for this purpose each fish will be assigned depends on the year in wich it was spawned and on the date of capture, simplifying the identification of annual class per fish.

This estimate is calculated with the number of rings observed in the otolith, the type of edge of the otolith and an arbitrary date of birth. In Chile, the first date of birth is taken as a convention on January 1.

GRUPO_EDAD <- function(x){
  
  m <- as.numeric(Age$MES)
  b <- as.numeric(Age$BORDE)
  im <- as.numeric(Age$Im)
  ge <- rep(NA, length(Age$Age))
  
  for(i in 1:length(x)){
    
    if(m[i] <= 5 & b[i] <= 2) 
      
      ge[i] <-  x[i] + 1
    
    else if(m[i] == 6 & b[i] == 1 & im[i] >= 0.250)
      
      ge[i] <-  x[i] + 1
    
    else if(m[i] == 6 & b[i] == 2)
      
      ge[i] <-  x[i] + 1
    
    else if(m[i] == 7 & b[i] == 1 & im[i] >= 0.350)
      
      ge[i] <-  x[i] + 1
    
    else if(m[i] == 7 & b[i] == 2) 
      
      ge[i] <-  x[i] + 1
    
    else if(m[i] == 8 & b[i] %in% c(1,2) & im[i] >= 0.500)
      
      ge[i] <- x[i] + 1 
    
    else if(m[i] == 9 & b[i] == 2 & im[i] >= 0.700)
      
      ge[i] <- x[i] + 1 
    
    else
      
      ge[i] = x[i]
    
  }
  
  return(ge)
  
}

Length weigth relationship

The length-weight relationship is widely used in fisheries to estimate weight from the length of an individual and also to estimate condition indices. The most frequently used expression for this relationship corresponds to the allometric equation where the weight is expressed as a function of length, and its parameters are estimated by linear regression of log-transformed data. Since variability in weight usually increases with length, this transformation has the advantage that it tends to stabilize the weight variance, but introduces a bias factor in back-transformed predictions which requires correction.

The weight/length model is:

\[W_i = a*L_i^b\] We can derive a simple linear regression model applying a logarithmic transformation:

\[ln(W_i) = ln(a)+b*ln(L_i)\]

where Wi represents the weight and Li the length of the i-th fish; a and b correspond to the intercept and slope, respectively.

AB <- function(x){
  ab <- x %>%
    filter(!is.na(LONGITUD_ESPECIMEN),
           !is.na(PESO_ESPECIMEN)) %>%
    group_by(ANO,MACROZONA,TRIMESTRE) %>% 
    mutate(L_LH = log(LONGITUD_ESPECIMEN),
           L_W = log(PESO_ESPECIMEN)) %>%
    summarise(Slope = lm(L_W ~ L_LH)$coefficients[2],
              Intercept = exp(lm(L_W ~ L_LH)$coefficients[1]),
              Correlation = cor(L_W,L_LH),
              N = n()) %>%
    mutate(bmax = round(Slope,1)) %>%
    left_join(PR,by = c("bmax")) %>%
    rename(tempbmax1 = bmax,
           tempA = temp1, 
           tempC = temp2 ) %>%
    mutate(bmax= round(round(Slope,1) - 0.1,1)) %>%
    left_join(PR,by = c("bmax")) %>%
    rename(tempbmax2 = bmax,
           tempB = temp1, 
           tempD = temp2) %>%
    mutate(a1 = as.numeric(tempA - ((tempbmax1 - Slope) * (tempA - tempB)) / (tempbmax1 - tempbmax2)),
           a2 = as.numeric(tempC - ((tempbmax1 - Slope) * (tempC - tempD)) / (tempbmax1 - tempbmax2))) %>%
    dplyr::select(-starts_with('temp'))
  
  return(ab)
  
}

Catch at age

Once a key is available, samples of fish that were only measured for length can be distributed to age groups accordingly.

This is possible because it assumes that the sample of aged fish and the sample of fish measured for length are simple random samples from the same population, thus the probability that a fish is of a particular age, given its length is the same in both samples follows.

The individuals present in each length interval (Nj) are assigned to different ages according to a size-age key.

The number of individuals belonging to each age group according to size interval is estimated as:

\[N_{ij} = q_{ij}/N_j\] where:

The abundance by age group is obtained by:

\[N_i = \sum_{i=1}^{n} N_{ij} \]

where:

Mean length

the average length for each age group is expressed as

\[ \bar{p_{i}} = \frac{\sum_{i=1}^{n} l_{j}n_{ij}}{ni} \]

Donde:

Variance

The variance of the mean length is expressed as

\[ P_i = \sum_{j=1} p_jq_{ij} \]

\[\sigma_{p_j} = \sum_{j=1}^{L} (\frac{p_j^{2}q_{ij}(1-q_{ij})}{n_{j}-1}+ \frac{p_{j}(q_{ij}-P_{i})^{2}}{N}) \]

Donde:

  • \(n_{j}\) : Estimated number of individuals of length j
  • N : sample Size
  • \(p_{j}\) : Sample size for each length stratum j
  • \(q_{ij}\) : Probability of individuals of length j belonging to an age group i

Mean weight

Assuming that the length is a normal random variable the expected function value of \(W_L\), will be defined as:

\[E(W) = a(\bar{p_{i}}^b+a_{1}\bar{p_{i}}^{b-2}\sigma^2+a_{2}\bar{p_{i}}^{b-4}\sigma^4)\]

where:

CATCH_AGE <- function(x){

  auxAge4 <- x
  
# LECTURAS DE EDAD CON TALLAS SIN ESTIMACION PARA CADA MACROZONA POR TRIMESTRE
  
  CaptTallaEdad <- auxAge4 %>% 
    group_by(CRITERIO,ANO,MACROZONA,TRIMESTRE,LONGITUD_ESPECIMEN,GRUPO_EDAD) %>%
    summarise(FREC = n()) %>%
    mutate(PROP_GRUPO = FREC/sum(FREC)) %>%
    left_join(Length, by = c("CRITERIO","ANO","MACROZONA","TRIMESTRE","LONGITUD_ESPECIMEN")) %>%
    mutate(CAPT = PROP_GRUPO*CAPT) %>%
    ungroup()
  
# CAPTURAS A LA EDAD Y TALLA POR CADA MACROZONA Y TRIMESTRE

  auxCatchAge <- CaptTallaEdad %>% 
    dplyr::select(CRITERIO,ANO,MACROZONA,TRIMESTRE,GRUPO_EDAD,CAPT) %>%
    group_by(CRITERIO,ANO,MACROZONA,TRIMESTRE,GRUPO_EDAD) %>%
    summarise(CAPT = sum(CAPT,na.rm=T)) %>%
    ungroup() %>%
    group_by(CRITERIO,ANO,MACROZONA, TRIMESTRE) %>%
    mutate(PORC =  CAPT/sum(CAPT,na.rm=T) *100)
  
  auxCatchAge1 <- CaptTallaEdad %>%
    mutate(tmed = LONGITUD_ESPECIMEN * CAPT, 
           varl = (LONGITUD_ESPECIMEN^2) * CAPT) %>%
    filter(CAPT != 0) %>%
    group_by(CRITERIO,ANO,MACROZONA,TRIMESTRE,GRUPO_EDAD) %>%
    summarise(VARL = sum(varl, na.rm = T),
              TMED = sum(tmed, na.rm = T))
  
  auxCatchAge2 <- CaptTallaEdad %>%
    filter(CAPT != 0) %>%
    group_by(CRITERIO,ANO,MACROZONA,TRIMESTRE,GRUPO_EDAD) %>%
    summarise(L_PR = weighted.mean(LONGITUD_ESPECIMEN, CAPT))

# CAPTURAS A LA EDAD
  
  CatchAge <- auxCatchAge %>%  
    left_join(auxCatchAge2,  by = c("CRITERIO","ANO","MACROZONA","TRIMESTRE","GRUPO_EDAD"))%>%
    left_join(ab, by = c("CRITERIO","ANO","MACROZONA","TRIMESTRE"))%>%
    dplyr::select(CRITERIO,ANO,MACROZONA,TRIMESTRE,GRUPO_EDAD,CAPT,PORC,L_PR,Intercept,
                  Slope, Correlation, N,a1,a2)%>%
    left_join(auxCatchAge1,by = c("CRITERIO","ANO","MACROZONA","TRIMESTRE","GRUPO_EDAD"))%>%
    ungroup()%>%
    mutate(VAR =    abs((VARL-(L_PR*TMED))/(CAPT-1)),
           P_PR = (Intercept * ((L_PR^Slope) + 
                                  a1 * (L_PR^(Slope-2)) * VAR +
                                  a2 * (L_PR^(Slope-4)) * VAR^2))/1000,
           CAPT_TON = (CAPT* P_PR) / 1000) %>%
    group_by(CRITERIO,ANO,MACROZONA,TRIMESTRE)%>%
    mutate(PORC_TON = (CAPT_TON / sum(CAPT_TON)) * 100)%>%
    ungroup()%>%
    dplyr::select(CRITERIO,ANO,MACROZONA,TRIMESTRE,GRUPO_EDAD,
                  CAPT,PORC,L_PR,VAR,P_PR,CAPT_TON, 
                  PORC_TON)%>% 
    ungroup() %>% 
    filter(CAPT != 0) %>%
    mutate(GE = "GE")%>% 
    unite(GRUPO_EDAD, GE,GRUPO_EDAD) %>%
    mutate(ANO = as.numeric(ANO)) %>%
    separate(GRUPO_EDAD, into = c("G","GRUPO_EDAD"), sep ="_") %>%
    mutate(GRUPO_EDAD = as.numeric(GRUPO_EDAD)) %>%
    dplyr::select(-G)

  return(list(CatchAge, CaptTallaEdad))

} 

References