Show code
load("benthicCoverXrefBenthicCodes.RData")This page aggregates the remaining benthic categories that are not coral, algae, sponges, gorgonians, or zoanthids into a single “other” grouping, then plots the percent cover of those categories through time at each survey site. The “other” grouping covers the benthic-code categories Turf and Non-living, which capture turf algae and non-living substrate reported alongside the living taxa. The main output is the faceted cover-over-time figure (Figure 1) and a downloadable long-format cover table (s2pt10_benthicCoverOther) that feeds the downstream resilience and biodiversity pages.
This page reads the reformatted benthic cover and cross-referenced benthic codes produced in sections 2.1 and 2.2 from the TCRMP and VINPS programs, which both record the Turf and Non-living categories. The CSUN program does not contribute these categories. It also uses the site master table to order facets by depth. The derived “other” cover table produced here is available in the Downloads section below.
TCRMP and VINPS both record replicate transects at each site, so their site-year means carry standard error, shown as the black linerange on total “other” cover. VINPS begins later than TCRMP, so the earliest years hold TCRMP sites only. Read program differences with these structures in mind and never pool a single error bar across programs.
What happens here: the page loads the per-program benthic cover and the benthic-code cross-reference produced by the section 2.1 reformat and the section 2.2 cross-referencing step, then names the grouping variable and the output section tag used later for file naming.
load("benthicCoverXrefBenthicCodes.RData")subfoldername names where the grouped cover products are written. groupingvar sets the grouping for this page (other). section tags the output filenames (s2pt10).
subfoldername <- "benthicCoverGrouped"
groupingvar <- "other"
section <- "s2pt10" # for namingbenthicDat into subgroupings of interestThe benthic-code cross-reference drops the TWS code and is filtered to the Turf and Non-living categories, so the grouping below covers exactly the “other” benthic categories reported on this page.
The shared cross-reference include below matches every program’s benthic-data columns to their “other” group, builds one grouped cover table per program, merges TCRMP and VINPS, and melts the result to long format. Its UAGA guard warns if any program’s data column carries a code absent from benthicCodes, so a category cannot be silently dropped.
getBenthicDatColInds()this is one of two functions that connect benthicDat to benthicCodes for all three programs.
getBenthicDatColInds() makes _columnInds that stores column indices of benthic codes corresponding to each item of other arguments:
benthicDat is benthic dataset of interest
codecolumn is the name of the column of benthic code containing the code for benthicdat
groupingcolumn is the name of the column of benthic codes where the grouping variable of interest is stored.
getBenthicDatColInds <-
function(benthicDat, codecolumn, groupingcolumn) {
codecolind <-
which(colnames(benthicCodes) == codecolumn)
groupingcolind <-
which(colnames(benthicCodes) == groupingcolumn)
genusdf <-
data.frame(group =
unique(benthicCodes[, groupingcolind]),
colinds =
rep(0, length(unique(benthicCodes[, groupingcolind]))))
for (i in 1:nrow(genusdf)) {
codei <-
benthicCodes[which(benthicCodes[, groupingcolind] == genusdf$group[i]), ]
genusdf$colinds[i] <-
list(which(colnames(benthicDat) %in% codei[, codecolind]))
}
# UAGA-guard: warn on benthicDat data columns whose code is absent from benthicCodes and is
# therefore silently dropped (the footgun that lost VINPS Agaricia agaricites, code UAGA).
.known <- benthicCodes[[codecolind]]; .known <- .known[nchar(.known) > 0]
.meta_cols <- c("program","date","site","period","replicate","replicatetype","nopts",
"Year","Date","SiteFullName","year","month","percentCover_allCoral",
"PC","Check","Notes","Transect")
.dropped <- setdiff(colnames(benthicDat), c(.known, .meta_cols))
if (length(.dropped) > 0)
warning("getBenthicDatColInds(", codecolumn, "): ", length(.dropped),
" data column(s) have codes absent from benthicCodes and are DROPPED: ",
paste(.dropped, collapse = ", "), " -- add them to benthicCodes if they are taxa.")
return(genusdf)
}apply getBenthicDatColInds() to _benthicDat dataframes . preview tcrmp_columnInds
tcrmp_columnInds <-
getBenthicDatColInds(tcrmp_benthicDat, "tcrmp_Code", "tcrmp_Meaning")
vinps_columnInds <-
getBenthicDatColInds(vinps_benthicDat, "vinps_TaxonCode", "tcrmp_Meaning")
kbl(tcrmp_columnInds) |>
kable_paper(full_width = F) |>
kable_styling(
fixed_thead = T,
bootstrap_options = c("hover", "condensed"),
font_size = 8
) |>
scroll_box(width = "100%", height = "250px")| group | colinds |
|---|---|
| Epilithic algae community | 107 |
| Boulder | 108 |
| Pavement | 109 |
| Rubble | 110 |
| Sand | 112 |
| Unknown | 114 |
makeGroupedBenthicDat()this is the second function that connects benthicDat to benthicCodes for all three programs.
makeGroupedBenthicDat() extracts the column indices (colinds) from each row of *_columnInds.
If only one index in colinds , assigns the corresponding column from benthicdat to the i-th column of a data frame _groupedBenthicDat.
if more than one index in colinds, stores row sum of benthicDat[,colinds] in the i-th column of _groupedBenthicDat.
arguments:
benthicDat is benthic dataset of interest
columnInds is the output of getBenthicDatColInds() above that contains column indices of benthic codes for each benthic subgroup of interest
makeGroupedBenthicDat <- function(benthicDat, columnInds) {
groupeddat <- data.frame(matrix(nrow = nrow(benthicDat),
ncol = nrow(columnInds)))
colnames(groupeddat) <- columnInds$group
benthicDat <- benthicDat %>% dplyr::mutate(dplyr::across(dplyr::where(is.numeric), ~replace(.x, is.na(.x), 0)))
for (i in 1:nrow(columnInds)) {
geni <- columnInds[i,]
datcoli <- unlist(geni$colinds)
if (length(datcoli) == 1) {
groupeddat[, i] <- benthicDat[, datcoli]
} else {
groupeddat[, i] <- rowSums(benthicDat[, datcoli])
}
}
groupeddat <- cbind(benthicDat[, 1:6], groupeddat)
return(groupeddat)
}apply makeGroupedBenthicDat() to _benthicDat and _columnInds . preview tcrmp_groupedBenthicDat.
tcrmp_groupedBenthicDat <-
makeGroupedBenthicDat(tcrmp_benthicDat, tcrmp_columnInds)
vinps_groupedBenthicDat <-
makeGroupedBenthicDat(vinps_benthicDat, vinps_columnInds)
kbl(head(tcrmp_groupedBenthicDat)) |>
kable_paper(full_width = F) |>
kable_styling(
fixed_thead = T,
bootstrap_options = c("hover", "condensed"),
font_size = 8
) |>
scroll_box(width = "100%", height = "250px")| program | date | site | period | replicate | replicatetype | Epilithic algae community | Boulder | Pavement | Rubble | Sand | Unknown |
|---|---|---|---|---|---|---|---|---|---|---|---|
| TCRMP | 2001-04-25 | Cane Bay | Annual | 1 | transect | 79.69 | 0 | 0 | 0 | 3.45 | 1.53 |
| TCRMP | 2001-04-25 | Cane Bay | Annual | 2 | transect | 59.38 | 0 | 0 | 0 | 1.95 | 0.78 |
| TCRMP | 2001-04-25 | Cane Bay | Annual | 3 | transect | 49.61 | 0 | 0 | 0 | 1.16 | 1.55 |
| TCRMP | 2001-04-25 | Cane Bay | Annual | 4 | transect | 47.46 | 0 | 0 | 0 | 3.99 | 0.72 |
| TCRMP | 2001-04-25 | Cane Bay | Annual | 5 | transect | 69.69 | 0 | 0 | 0 | 0.79 | 0.39 |
| TCRMP | 2001-04-25 | Cane Bay | Annual | 6 | transect | 60.15 | 0 | 0 | 0 | 3.76 | 1.50 |
benthicDat from three programsnow have three _groupedBenthicDat, need to merge them, start by comparing the column names, because some are missing from csun.
make sure each _groupedBenthicDat has the same column names
for (col in missing_columns_tcrmp) {
tcrmp_groupedBenthicDat[[col]] <- NA
}
for (col in missing_columns_vinps) {
vinps_groupedBenthicDat[[col]] <- NA
}tcrmp_groupedBenthicDat <- tcrmp_groupedBenthicDat[, all_columns]
vinps_groupedBenthicDat <- vinps_groupedBenthicDat[, all_columns]groupedBenthicDat.groupedBenthicDat <-
rbind(tcrmp_groupedBenthicDat,
vinps_groupedBenthicDat)groupedBenthicDat into long format.For TCRMP and VINPS, the page calculates annual transect-averaged percent cover of the “other” categories at each site. Total “other” cover is summed within each transect first, then averaged across transects with standard error, so the black total-cover points and their linerange reflect site-year replication.
totaldatCovSum <- groupedBenthicDat |>
dplyr::group_by(year, date, program, site, period, replicate) |>
dplyr::summarise(perccover = sum(perccover))
totaldatCovSum <- totaldatCovSum |>
dplyr::group_by(year, date, program, site) |>
dplyr::summarise(
meancov = mean(perccover),
sdcov = sd(perccover),
secov = sd(perccover) / (sqrt(length(perccover))),
n = length(perccover)
)
totaldatCovSum <- totaldatCovSum %>% dplyr::mutate(dplyr::across(dplyr::where(is.numeric), ~replace(.x, is.na(.x), 0)))groupedBenthicDatCovSum <- groupedBenthicDat |>
dplyr::group_by(year, date, program, site, other) |>
dplyr::summarise(
meancov = mean(perccover),
sdcov = sd(perccover),
secov = sd(perccover) / (sqrt(length(perccover))),
n = length(perccover)
)
groupedBenthicDatCovSum <- groupedBenthicDatCovSum %>% dplyr::mutate(dplyr::across(dplyr::where(is.numeric), ~replace(.x, is.na(.x), 0)))Figure 1 shows how each “other” category’s cover changes through time at every TCRMP and VINPS site, with facets ordered shallow to deep so depth patterns read down the panel. Stacked areas give each category’s contribution, and the black points with linerange give total “other” cover with standard error.
#add site info so can plot according to increasing depth
groupedBenthicDatCovSum <-
merge(groupedBenthicDatCovSum, sitedat, by = "site")
groupedBenthicDatCovSum <-
groupedBenthicDatCovSum[order(groupedBenthicDatCovSum$depth), ]
groupedBenthicDatCovSum$site <- factor(groupedBenthicDatCovSum$site,
levels = unique(groupedBenthicDatCovSum$site))
#add site info so can plot according to increasing depth
totaldatCovSum <-
merge(totaldatCovSum, sitedat, by = "site")
totaldatCovSum <-
totaldatCovSum[order(totaldatCovSum$depth), ]
totaldatCovSum$site <- factor(totaldatCovSum$site,
levels = unique(totaldatCovSum$site))
stack <- ggplot() +
geom_area(data = groupedBenthicDatCovSum,
aes(x = year, y = meancov, fill = other),
position = 'stack') +
# geom_line(data = totaldatCovSum, aes(x=year, y= meancov),color="black")+
geom_point(
data = totaldatCovSum,
aes(x = year, y = meancov),
color = "black",
size = 0.5
) +
geom_linerange(
data = totaldatCovSum,
aes(
x = year,
ymin = meancov - secov,
ymax = meancov + secov
),
color = "black",
linewidth = 0.5
) +
facet_wrap( ~ site, scales = "free_x") +
ylab("percent cover") +
scale_y_continuous(expand = c(0, 0)) +
scale_x_continuous(
expand = expansion(mult = 0.04),
breaks = seq(minyear, maxyear, by = 1),
labels = function(x)
ifelse(x %% 5 == 0, paste0("'", substr(x, 3, 4)), "")
) +
geom_vline(
xintercept = 2005,
color = "gray50",
alpha = 0.5,
lty = "dashed"
) +
theme_bw() +
theme(strip.text = element_text(size = 10)) +
theme(legend.position = "bottom") +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
stack
# svg(filename="gorgzo.svg", width = 10, height =8)
# stack
# dev.off()
The “other” categories track turf algae and non-living substrate, which together often occupy a large share of the benthos where coral and macroalgae cover is low. The site facets show how that share shifts through the record, with TCRMP sites carrying the earliest years before VINPS surveys begin.
What happens here: the page writes the long-format “other” cover table and its metadata to the shared outputs folder, then offers both plus the page source for download.
The “other” cover table (s2pt10_benthicCoverOther), its metadata, and this page’s .qmd source download below.
version 1.0.0 • in-review • data ≤ 2023