cv_intraspecific(df, sp_col, trait_cols)

Coefficient of variation (CV) within each species for each trait. Quantifies intraspecific variability as a proportion of the species mean.

ITVstatistics
Args:df — individual-level datasp_col — species columntrait_cols — trait columns
cv_intraspecific <- function(df, sp_col, trait_cols) {
  sp_list <- unique(df[[sp_col]])
  
  do.call(rbind, lapply(sp_list, function(sp) {
    sub <- df[df[[sp_col]] == sp, trait_cols, drop = FALSE]
    n   <- nrow(sub)
    
    cvs <- sapply(sub, function(x) {
      x <- x[!is.na(x)]
      if (length(x) < 2) return(NA_real_)
      sd(x) / abs(mean(x)) * 100  # CV in %
    })
    
    data.frame(species = sp, n = n,
               t(cvs), stringsAsFactors = FALSE)
  }))
}

# Example usage:
# cv_intraspecific(fish_data, sp_col = "species", trait_cols = c("BL","BD","HL"))
# ── Example ──────────────────────────────────────────────────────
# iris: 3 species, 4 morphological traits
result <- cv_intraspecific(iris,
                           sp_col     = "Species",
                           trait_cols = c("Sepal.Length","Sepal.Width",
                                          "Petal.Length","Petal.Width"))
print(result)
# Interpretation: high CV = high intraspecific variability for that trait