Quantitative ethnoecology analysis with ethnoecologyR

Marwan Setiawan, BRIN

2026-11-06

Quantitative ethnoecology analysis with ethnoecologyR

Marwan Setiawan, BRIN

Please remember to cite the ethnoecologyR package if you use it in your publications. Use citation("ethnoecologyR") to get a citation for the latest version.

To cite package ‘ethnoecologyR’ in publications use:

Marwan Setiawan (2026). ethnoecologyR: Quantitative Ethnoecology Analysis and Landscape Knowledge Modeling. R package version 0.1.5.

A Critical Perspective on Ethnoecology Indices

Quantitative ethnoecology is the study of the use and importance of landscape units and ecosystems in human cultures, using statistical and analytical methods to quantify and interpret data. This approach has emerged as a key tool for understanding the cultural and ecological significance of landscape units, and for evaluating the impact of human activities on ecosystems.

While widely used in the literature, traditional ethnoecology indices have significant limitations that researchers should consider:

When to use these indices:

When to avoid these indices:

Using the ethnoecologyR package

The ethnoecologyR package offers quantitative tools to assess the cultural significance of landscape units based on informant consensus. The package closely follows several key papers on ethnoecology indices (Tardío and Pardo-de-Santayana 2008; Friedman et al. 1986; Reyes-García et al. 2006; Toledo 2002). The goal is to provide an easy-to-use platform for ethnoecologists to perform quantitative ethnoecology assessments.

Users are highly encouraged to familiarize themselves with ethnoecology theory (Berkes 2012; Toledo 2002) and social-ecological systems theory (Ostrom 2009). An overview of this theoretical background will be helpful in understanding approaches in ethnoecology and formulating useful research questions.

An example data set called ethnoecology_data is provided to show how standard quantitative ethnoecology data should be formatted to interface with the ethnoecologyR package. This is an ethnoecology data set including one column of knowledge-holder identifiers informant, one column of landscape unit names landscape_unit, and several binary columns for ethnoecology use categories. The data in the use-category columns are counts of uses per person (0 or 1).

First six rows of the example ethnoecology data included with ethnoecologyR
informant landscape_unit use_forest use_water use_agriculture use_hunting use_fishing use_gathering
Info_1 Landscape_1 1 1 0 0 0 0
Info_1 Landscape_2 1 0 1 0 0 0
Info_1 Landscape_3 1 0 1 0 0 1
Info_1 Landscape_4 1 1 0 1 0 1
Info_1 Landscape_5 1 0 0 0 0 0
Info_1 Landscape_6 0 1 1 1 0 1

Many of the functions in ethnoecologyR make use of select() and filter() functions of the dplyr package (Wickham et al. 2026) and pipe functions %>% from the magrittr package (Bache and Wickham 2025). The intention is that these should be easy to understand and use, and that they should allow users the chance to pull the code for these functions and change anything they see fit.

Data preparation with ethno_data_prep()

Before running any analyses, data can be reshaped with ethno_data_prep(). This helper returns a cleaned data frame in either wide (pivot_long = FALSE) or long (pivot_long = TRUE, default) format, which is convenient for downstream functions that expect use_category columns.

long_data <- ethno_data_prep(ethnoecology_data, pivot_long = TRUE)
knitr::kable(head(long_data, 8),
             caption = "Long-format data returned by ethno_data_prep()")
Long-format data returned by ethno_data_prep()
informant landscape_unit use_category value
Info_1 Landscape_1 use_forest 1
Info_1 Landscape_1 use_water 1
Info_1 Landscape_2 use_forest 1
Info_1 Landscape_2 use_agriculture 1
Info_1 Landscape_3 use_forest 1
Info_1 Landscape_3 use_agriculture 1
Info_1 Landscape_3 use_gathering 1
Info_1 Landscape_4 use_forest 1

Ethnoecology indices functions

Ethnoecology indices are numerical measures used to quantify the importance of landscape units in different cultural or ecological contexts. Several common ethnoecology indices are implemented in ethnoecologyR. These indices allow researchers to compare the relative importance of different landscape units within a particular culture or ecosystem.

The standard quantitative ethnoecology indices are probably too narrow a tool for a proper assessment of human-ecological interactions. Still, they offer a useful entry into understanding some aspects of how human communities interact with nature. The steps required to calculate these indices offer a way to quantify intangible factors of how human communities interact with the world. They can come in handy as additive pieces for more holistic assessments and analyses.

Landscape Use (LU)

The Landscape Use (LU) index is a measure of the overall importance of a landscape unit based on the total number of use reports. It is calculated as:

LU = sum of use reports for a landscape unit

lu_result <- LUs(ethnoecology_data)
knitr::kable(lu_result, caption = "Landscape Use index (LU)")
Landscape Use index (LU)
landscape_unit LU
Landscape_3 51
Landscape_2 49
Landscape_1 44
Landscape_4 44
Landscape_6 43
Landscape_5 39
plot_index(lu_result, "LU", "Landscape Use (LU)")
Landscape Use (LU) per landscape unit

Landscape Use (LU) per landscape unit

Cultural Importance in Ecology (CIE)

The Cultural Importance in Ecology (CIE) index is a normalized measure of use intensity. It is calculated as:

CIE = LU / N, where N is the number of informants.

cie_result <- CIEs(ethnoecology_data)
knitr::kable(cie_result, digits = 3, caption = "Cultural Importance in Ecology (CIE)")
Cultural Importance in Ecology (CIE)
landscape_unit total_informants total_uses CIE
Landscape_3 15 51 3.400
Landscape_2 15 49 3.267
Landscape_1 15 44 2.933
Landscape_4 15 44 2.933
Landscape_6 15 43 2.867
Landscape_5 15 39 2.600
plot_index(cie_result, "CIE", "Cultural Importance in Ecology (CIE)")
Cultural Importance in Ecology (CIE) per landscape unit

Cultural Importance in Ecology (CIE) per landscape unit

Frequency of Citation (FC)

The Frequency of Citation (FC) is the number of informants who mention a landscape unit for any use.

fc_result <- FCs_eco(ethnoecology_data)
knitr::kable(fc_result, caption = "Frequency of Citation (FC)")
Frequency of Citation (FC)
landscape_unit FC
Landscape_1 15
Landscape_2 15
Landscape_3 15
Landscape_4 15
Landscape_5 15
Landscape_6 15
plot_index(fc_result, "FC", "Frequency of Citation (FC)")
Frequency of Citation (FC) per landscape unit

Frequency of Citation (FC) per landscape unit

Fidelity Level (FL)

The Fidelity Level (FL) is the percentage of informants who mention a landscape unit for a specific use category. It is calculated as:

FL = (number of informants mentioning the unit for a specific use / total number of informants mentioning the unit for any use) × 100

fl_result <- FLs_eco(ethnoecology_data, "use_forest")
knitr::kable(fl_result, digits = 1, caption = "Fidelity Level (FL) for use_forest")
Fidelity Level (FL) for use_forest
landscape_unit total_informants specific_informants FL
Landscape_1 15 13 86.7
Landscape_3 15 13 86.7
Landscape_2 15 12 80.0
Landscape_5 15 11 73.3
Landscape_6 15 11 73.3
Landscape_4 15 6 40.0
plot_index(fl_result, "FL", "Fidelity Level (FL) — use_forest")
Fidelity Level (FL) for the use_forest category

Fidelity Level (FL) for the use_forest category

Number of Uses (NU)

The Number of Uses (NU) is the total number of distinct use categories reported for each landscape unit.

nu_result <- NUs_eco(ethnoecology_data)
knitr::kable(nu_result, caption = "Number of Uses (NU)")
Number of Uses (NU)
landscape_unit NU
Landscape_1 6
Landscape_2 6
Landscape_3 6
Landscape_4 6
Landscape_5 6
Landscape_6 6
plot_index(nu_result, "NU", "Number of Uses (NU)")
Number of Uses (NU) per landscape unit

Number of Uses (NU) per landscape unit

Cultural Value of Ecolandscape (CVe)

The Cultural Value of Ecolandscape (CVe) is a composite index combining LU and FC. It is calculated as:

CVe = (LU / N) × (FC / N)

cv_result <- CVe_eco(ethnoecology_data)
knitr::kable(cv_result, digits = 3, caption = "Cultural Value (CVe)")
Cultural Value (CVe)
landscape_unit LU FC CVe
Landscape_3 51 15 3.400
Landscape_2 49 15 3.267
Landscape_1 44 15 2.933
Landscape_4 44 15 2.933
Landscape_6 43 15 2.867
Landscape_5 39 15 2.600
plot_index(cv_result, "CVe", "Cultural Value (CVe)")
Cultural Value (CVe) per landscape unit

Cultural Value (CVe) per landscape unit

Ranking with ethno_ranking()

ethno_ranking() takes any index function (e.g., CIEs, NUs_eco) and returns the top n landscape units ranked by that index. This is useful for rapid identification of priority units.

top_cie <- ethno_ranking(ethnoecology_data,
                         index_function = CIEs,
                         top_n = 5)
knitr::kable(top_cie, digits = 3, caption = "Top 5 landscape units by CIE")
Top 5 landscape units by CIE
landscape_unit Index_Value total_uses CIE
Landscape_3 15 51 3.400
Landscape_2 15 49 3.267
Landscape_1 15 44 2.933
Landscape_4 15 44 2.933
Landscape_6 15 43 2.867
plot_index(top_cie, "CIE", "Top 5 landscape units by CIE")
Top 5 landscape units by Cultural Importance (CIE)

Top 5 landscape units by Cultural Importance (CIE)

Richness with ethno_richness()

ethno_richness() computes richness (the number of distinct items) per group. When the default count_col = "species" is not present, the function automatically falls back to an available identifier and emits an informational message.

rich_result <- ethno_richness(ethnoecology_data, group_by = "landscape_unit")
knitr::kable(rich_result, caption = "Richness per landscape unit")
Richness per landscape unit
landscape_unit Richness
Landscape_1 15
Landscape_2 15
Landscape_3 15
Landscape_4 15
Landscape_5 15
Landscape_6 15
plot_index(rich_result, "Richness", "Richness per landscape unit")
Richness per landscape unit

Richness per landscape unit

Habitat × Use analysis with ethno_habitat_analysis()

ethno_habitat_analysis() cross-tabulates the number of use reports per habitat and use category. It automatically detects use_* columns in wide-format data, and also accepts long-format input through the use_col argument.

hab_result <- ethno_habitat_analysis(ethnoecology_data)
knitr::kable(hab_result, caption = "Habitat × use-category cross-table")
Habitat × use-category cross-table
landscape_unit agriculture fishing forest gathering hunting water
Landscape_1 8 3 13 4 6 10
Landscape_2 11 8 12 7 5 6
Landscape_3 10 7 13 9 7 5
Landscape_4 9 3 6 10 4 12
Landscape_5 9 2 11 6 3 8
Landscape_6 10 4 11 8 4 6

Working with figures

Figures help to visually represent the main ideas or key results of ethnoecology work. The following sections walk through the visualization functions provided by ethnoecologyR.

Chord diagrams with circlize

The chord plots are built with the circlize package (Gu 2022). An example of chord plots in ethnoecology is described by Whitney, Bahati, and Gebauer (2018).

The ethno_landscape_chord() function creates a chord diagram of ethnoecology uses and landscape units.

ethno_landscape_chord(ethnoecology_data, by = "landscape_unit")
Chord diagram of landscape units and uses

Chord diagram of landscape units and uses

The function can also produce a chord diagram of informants and uses.

ethno_landscape_chord(ethnoecology_data, by = "informant")
Chord diagram of informants and uses

Chord diagram of informants and uses

Alluvial plots with ggalluvial

The ethno_landscape_alluvial() function creates an alluvial diagram showing flows between informants, landscape units, and ecological uses.

ethno_landscape_alluvial(ethnoecology_data)
Alluvial plot of landscape uses

Alluvial plot of landscape uses

Bipartite network with ethno_landscape_network()

ethno_landscape_network() produces a bipartite network between landscape units (or informants, when by = "informant") and use categories. Nodes represent landscape units and use categories; edges connect a unit to the categories it provides. The function uses a Fruchterman–Reingold force-directed layout.

Because the function accepts both wide and long formats, users can pass data straight from a field spreadsheet without reshaping.

ethno_landscape_network(ethnoecology_data, by = "landscape_unit")
Bipartite network of landscape units and use categories

Bipartite network of landscape units and use categories

Radial plot with landscape_radial_plot()

The landscape_radial_plot() function creates a radial bar plot for one or more ethnoecology indices per landscape unit. The indices_list argument must be a list of functions (not a list of results), so the function can compute each index internally.

landscape_radial_plot(ethnoecology_data, list(LUs, CIEs, FCs_eco))
Radial plot of three ethnoecology indices

Radial plot of three ethnoecology indices

Combine several indices in a single grid

For side-by-side comparison, multiple radial plots can be combined into a single publication-ready figure with cowplot::plot_grid().

library(cowplot)

plots <- list(
  LU  = landscape_radial_plot(ethnoecology_data, list(LUs)),
  CIE = landscape_radial_plot(ethnoecology_data, list(CIEs)),
  FC  = landscape_radial_plot(ethnoecology_data, list(FCs_eco)),
  NU  = landscape_radial_plot(ethnoecology_data, list(NUs_eco))
)

cowplot::plot_grid(
  plotlist    = plots,
  labels      = names(plots),
  nrow        = 2,
  align       = "hv",
  label_size  = 14
)
Comparison of four ethnoecology indices in a 2×2 grid

Comparison of four ethnoecology indices in a 2×2 grid

Note: Warnings about “Removed N rows containing missing values” may appear when the supplied indices do not cover identical sets of landscape units. This is expected behaviour: rows with missing values are dropped by ggplot2.

Landscape Resilience Index (LRI)

The ethno_resilience() function computes a composite Landscape Resilience Index (LRI) per landscape unit. The LRI is defined as the sum of three normalised components:

LRI = (UV / max(UV)) + (FL / max(FL)) + (H / max(H))

This index provides a single score that captures both the intensity and the diversity of landscape use. It is intended as a starting point for identifying landscape units that combine high use pressure with high functional redundancy.

lri_result <- ethno_resilience(ethnoecology_data)
knitr::kable(lri_result, digits = 3, caption = "Landscape Resilience Index (LRI)")
Landscape Resilience Index (LRI)
landscape_unit UV FL H LRI
Landscape_3 51 6 1.747 3.000
Landscape_2 49 6 1.744 2.959
Landscape_4 44 6 1.688 2.829
Landscape_6 43 6 1.717 2.826
Landscape_1 44 6 1.680 2.824
Landscape_5 39 6 1.658 2.714
plot_index(lri_result, "LRI", "Landscape Resilience Index (LRI)")
Landscape Resilience Index (LRI) per landscape unit

Landscape Resilience Index (LRI) per landscape unit

Bayesian Consensus Modeling

ethno_bayes_land() fits a Bayesian model that estimates consensus among informants regarding landscape use. The model is fitted using Hamiltonian Monte Carlo via rstan (Stan Development Team 2024). Because compilation and sampling are time-intensive, the example is shown but not executed here.

fit <- ethno_bayes_land(ethnoecology_data, iter = 500, chains = 2)
print(fit, pars = c("theta[1]", "theta[2]", "theta[3]"))

Bootstrap Confidence Intervals

ethno_boot_land() computes bootstrap confidence intervals for any index function, providing a non-parametric estimate of uncertainty. The R argument controls the number of resamples.

set.seed(42)
boot_ci <- ethno_boot_land(ethnoecology_data,
                           index_function = CIEs,
                           R = 100)
print(boot_ci)
#> 
#> ORDINARY NONPARAMETRIC BOOTSTRAP
#> 
#> 
#> Call:
#> boot::boot(data = data, statistic = boot_stat, R = R)
#> 
#> 
#> Bootstrap Statistics :
#>     original  bias    std. error
#> t1*       15   -5.61    2.136243
#> t2*       15   -5.58    1.627913
#> t3*       15   -5.39    1.757495
#> t4*       15   -5.14    1.735081
#> t5*       15   -5.44    1.628782
#> t6*       15   -5.34    1.429982

Full workflow example

The following minimal example strings together the main steps of a quantitative ethnoecology analysis. Users can copy and adapt this code as a starting template for their own data.

library(ethnoecologyR)
library(dplyr)
library(ggplot2)

# 1. Load data
data(ethnoecology_data)

# 2. Prepare
long <- ethno_data_prep(ethnoecology_data, pivot_long = TRUE)

# 3. Core indices
lu  <- LUs(ethnoecology_data)
cie <- CIEs(ethnoecology_data)
nu  <- NUs_eco(ethnoecology_data)

# 4. Rank landscape units by cultural importance
top <- ethno_ranking(ethnoecology_data, index_function = CIEs, top_n = 5)
print(top)

# 5. Habitat × use cross-table
habitat <- ethno_habitat_analysis(ethnoecology_data)
print(habitat)

# 6. Resilience index
lri <- ethno_resilience(ethnoecology_data)
print(lri)

# 7. Visualizations
ethno_landscape_network(ethnoecology_data)
ethno_landscape_alluvial(ethnoecology_data)
landscape_radial_plot(ethnoecology_data, list(LUs, CIEs, FCs_eco))

Troubleshooting

Error message Likely cause Solution
Column 'use_category' not found Data passed in wide format but function requires long Use ethno_data_prep(data, pivot_long = TRUE) first, or rely on auto-detection where supported
Column 'species' not found ethno_richness() cannot find the default count column Pass count_col = "your_column", or accept the automatic fallback
argument "index_function" is missing Function requires an index function e.g., ethno_ranking(data, index_function = CIEs, top_n = 5)
argument "use_category" is missing FLs_eco() needs a specific use category e.g., FLs_eco(data, use_category = "use_forest")
Removed N rows containing missing values Two indices cover different landscape units Expected behaviour; ensure all indices are computed on the same set of units
Stan compilation warnings rstan / Rtools not installed Install rstan and Rtools4.x, then restart R
object 'data_super' not found R session restarted without re-reading the source spreadsheet Re-run the readxl::read_excel() call that created the data

Conclusions

Quantitative ethnoecology offers a way to study the use and importance of landscape units in human cultures, using statistical and analytical methods to quantify and interpret data. This approach is useful in a variety of contexts, including:

One of the main benefits of quantitative ethnoecology is that it allows researchers to rigorously and systematically analyse and interpret data, providing more reliable and objective insights into the role of landscape units in different cultural and ecological settings.

Overall, the ethnoecologyR package provides a comprehensive set of tools for researchers and practitioners working in ethnoecology and related fields. By using these standardized methods and statistical analyses, researchers can more accurately compare and contrast the importance of different landscape units and evaluate the significance of their findings.

Acknowledgements

This work was inspired by the pioneering contributions of:

The vignette was written and formatted using the tools provided by the knitr package (Xie 2025).

References

Bache, Stefan Milton, and Hadley Wickham. 2025. Magrittr: A Forward-Pipe Operator for R. https://magrittr.tidyverse.org.

Berkes, F. 2012. Sacred Ecology. 3rd ed. Routledge.

Canty, A., and B. Ripley. 2024. boot: Bootstrap R (S-Plus) Functions. R package version 1.3-30.

Friedman, J., Z. Yaniv, A. Dafni, and D. Palewitch. 1986. “A Preliminary Classification of the Healing Potential of Medicinal Plants, Based on a Rational Analysis of an Ethnopharmacological Field Survey Among Bedouins in the Negev Desert, Israel.” Journal of Ethnopharmacology 16(2-3): 275-287.

Gu, Z. 2022. circlize: Circular Visualization. R package version 0.4.15.

Ostrom, E. 2009. “A General Framework for Analyzing Sustainability of Social-Ecological Systems.” Science 325(5939): 419-422.

R Core Team. 2025. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria.

Reyes-García, V., T. Huanca, V. Vadez, W. Leonard, and D. Wilkie. 2006. “Cultural, Practical, and Economic Value of Wild Plants: A Quantitative Study in the Bolivian Amazon.” Economic Botany 60(1): 62-74.

Stan Development Team. 2024. RStan: The R Interface to Stan. R package version 2.32.6.

Tardío, J., and M. Pardo-de-Santayana. 2008. “Cultural Importance Indices: A Comparative Analysis Based on the Useful Wild Plants of Southern Cantabria (Northern Spain).” Economic Botany 62(1): 24-39.

Toledo, V. M. 2002. “Ethnoecology: A Conceptual Framework for the Study of Indigenous Knowledge of Nature.” In Ethnobiology and Biocultural Diversity, edited by J. R. Stepp, F. S. Wyndham, and R. K. Zarger, 511-522. University of Georgia Press.

Whitney, C. W., J. Bahati, and J. Gebauer. 2018. “Ethnobotany and Agrobiodiversity: Valuation of Plants in the Homegardens of Southwestern Uganda.” Ethnobiology Letters 9(2): 1-12.

Wickham, H., et al. 2026. dplyr: A Grammar of Data Manipulation. R package version 1.1.0.

Wickham, H., and L. Henry. 2026. purrr: Functional Programming Tools. R package version 1.0.0.

Wickham, H., D. Vaughan, and M. Girlich. 2025. tidyr: Tidy Messy Data. R package version 1.3.0.

Xie, Y. 2025. knitr: A General-Purpose Package for Dynamic Report Generation in R. R package version 1.45.