Type: Package
Title: Analyse Soil Tillage Depth and Erosion Over Time
Version: 0.1.0
Description: Provides tools to record, validate, and analyse soil tillage depth and erosion across years and field treatments. Includes functions for year-wise tillage operation summaries, erosion depth tracking, compaction detection, soil loss estimation, and visualisation of temporal changes in tillage and erosion profiles. Methods follow Lal (2001) <doi:10.1201/9780203739280> and Renard et al. (1997) "Predicting Soil Erosion by Water: A Guide to Conservation Planning with the Revised Universal Soil Loss Equation (RUSLE)" https://ntrl.ntis.gov/NTRL/dashboard/searchResults/titleDetail/PB97153704.xhtml.
License: MIT + file LICENSE
Encoding: UTF-8
Language: en-US
LazyData: true
LazyDataCompression: bzip2
Depends: R (≥ 3.5.0)
Imports: dplyr (≥ 1.1.0), ggplot2 (≥ 3.4.0)
Suggests: testthat (≥ 3.0.0), knitr, rmarkdown
VignetteBuilder: knitr
Config/testthat/edition: 3
RoxygenNote: 7.3.3
NeedsCompilation: no
Packaged: 2026-03-19 08:44:10 UTC; acer
Author: Sadikul Islam ORCID iD [aut, cre]
Maintainer: Sadikul Islam <sadikul.islamiasri@gmail.com>
Repository: CRAN
Date/Publication: 2026-03-23 17:30:02 UTC

soiltillr: Analyse Soil Tillage Depth and Erosion Over Time

Description

Provides tools to record, validate, and analyse soil tillage depth and erosion across years and field treatments. Includes functions for year-wise tillage operation summaries, erosion depth tracking, compaction detection, soil loss estimation, and visualisation of temporal changes in tillage and erosion profiles.

Validation

validate_soil_data

Checks a data frame for missing columns, negative values, empty rows, and implausible year values before any analysis.

Tillage analysis

summarise_tillage

Year x field summary: n_operations, mean/max/total depth, dominant operation type.

tillage_depth_trend

Year-on-year change in mean tillage depth per field; classifies each year as "baseline", "increasing", "decreasing", or "stable".

detect_compaction

Compaction risk ("high", "moderate", "low") and estimated plow pan depth from tillage records.

Erosion analysis

track_erosion_depth

Annual erosion depth, year-on-year change, cumulative loss, and trend direction per field.

estimate_soil_loss

Mass-balance soil loss estimate (t/ha) using erosion depth, bulk density, and an optional McCool LS slope correction.

compare_fields

Wide-format year-by-year comparison of erosion depth and organic matter between two or more fields.

Visualisation

plot_tillage_timeline

Line plot of mean annual tillage depth by field.

plot_erosion_trend

Line plot of annual erosion depth; optional cumulative panel.

plot_om_trend

Soil organic matter (\

plot_tillage_erosion

Dual-panel figure comparing tillage depth and erosion depth.

Built-in datasets

tillage_operations

20-row hypothetical tillage records for Field_A and Field_B (2018–2023).

erosion_profile

12-row hypothetical annual erosion and soil health measurements for the same fields.

Author(s)

Sadikul Islam sadikul.islamiasri@gmail.com (ORCID: 0000-0003-2924-7122)

References

Lal, R. (2001). Soil degradation by erosion. Land Degradation and Development, 12(6), 519–539. doi:10.1002/ldr.472

McCool, D. K., Brown, L. C., Foster, G. R., Mutchler, C. K., & Meyer, L. D. (1987). Revised slope steepness factor for the Universal Soil Loss Equation. Transactions of the ASAE, 30(5), 1387–1396. doi:10.13031/2013.30576

Renard, K. G., Foster, G. R., Weesies, G. A., McCool, D. K., & Yoder, D. C. (1997). Predicting Soil Erosion by Water: A Guide to Conservation Planning with the Revised Universal Soil Loss Equation (RUSLE). USDA Agriculture Handbook No. 703. https://ntrl.ntis.gov/NTRL/dashboard/searchResults/titleDetail/PB97153704.xhtml


Compare Erosion and Organic Matter Between Fields

Description

Produces a year-by-year side-by-side comparison of erosion depth and organic matter content between two or more fields, showing absolute differences and relative change.

Usage

compare_fields(data, year_col, field_col, erosion_col, om_col)

Arguments

data

A data frame containing annual erosion and soil measurements.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

erosion_col

Character string. Name of the erosion depth column (mm).

om_col

Character string. Name of the organic matter column (percent).

Value

A data frame with one row per year containing erosion and organic matter values for each field as separate columns, plus difference columns.

Examples

data(erosion_profile)
comparison <- compare_fields(erosion_profile, "year", "field_id",
                             "erosion_depth_mm", "organic_matter_pct")
print(comparison)

Detect Soil Compaction from Tillage Records

Description

Identifies years where tillage practices are likely to cause or worsen soil compaction based on tillage depth, frequency, and operation type. Deep primary tillage (moldboard plowing) followed by shallow secondary tillage creates a compaction layer (plow pan) just below tillage depth.

Usage

detect_compaction(
  data,
  year_col,
  field_col,
  depth_col,
  op_col = NULL,
  compaction_threshold_cm = 20
)

Arguments

data

A data frame containing tillage operation records.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

depth_col

Character string. Name of the tillage depth column (cm).

op_col

Optional character string. Name of the operation type column.

compaction_threshold_cm

Numeric. Depth threshold (cm) above which tillage is considered to risk creating a plow pan (default: 20).

Value

A data frame with columns:

year

Year.

field_id

Field identifier.

mean_depth_cm

Mean tillage depth (cm).

compaction_risk

Risk level: "high", "moderate", or "low".

plow_pan_depth_cm

Estimated plow pan depth (cm): just below mean tillage depth.

Examples

data(tillage_operations)
risk <- detect_compaction(tillage_operations, "year", "field_id",
                          "depth_cm", op_col = "operation")
print(risk)

Soil Erosion Profile Dataset

Description

Hypothetical annual soil erosion measurements for two agricultural fields (Field_A and Field_B) over six years (2018–2023), including erosion depth, soil loss, bulk density, organic matter, rainfall, and slope.

Usage

data(erosion_profile)

Format

A data frame with 12 rows and 8 columns:

year

integer. Calendar year of measurement.

field_id

character. Field identifier: "Field_A" or "Field_B".

erosion_depth_mm

numeric. Annual soil erosion depth in millimetres.

soil_loss_t_ha

numeric. Annual soil loss in tonnes per hectare.

bulk_density_g_cm3

numeric. Topsoil bulk density in g/cm^3.

organic_matter_pct

numeric. Topsoil organic matter content as percentage by weight.

rainfall_mm

numeric. Annual rainfall in millimetres.

slope_pct

numeric. Field slope as percentage. Fixed at 4.5% for Field_A and 2.8% for Field_B.

Details

Field_A shows declining erosion depth and soil loss as tillage management shifts from conventional to conservation practices over the study period. Bulk density initially increases due to deep plowing compaction, then decreases as conservation tillage improves soil structure. Organic matter follows an inverse pattern, declining under intensive tillage and recovering under conservation management.

Field_B maintains consistently lower erosion and higher organic matter throughout, demonstrating the long-term benefit of reduced tillage.

This dataset is designed for use with track_erosion_depth(), detect_compaction(), estimate_soil_loss(), and plot_erosion_trend().

Source

Hypothetical data generated for package illustration purposes.

References

Lal, R. (2001). Soil degradation by erosion. Land Degradation and Development, 12(6), 519–539. doi:10.1002/ldr.472

Examples

data(erosion_profile)

# View structure
str(erosion_profile)

# Track erosion depth over years
result <- track_erosion_depth(erosion_profile, "year", "field_id",
                              "erosion_depth_mm")
print(result)

Estimate Annual Soil Loss

Description

Estimates annual soil loss in tonnes per hectare using a simplified approach based on erosion depth, bulk density, and field slope. If soil_loss_col is already present in the data, it is returned directly with a comparison to the estimated value.

Usage

estimate_soil_loss(
  data,
  year_col,
  field_col,
  erosion_col,
  bulk_density_col,
  slope_col = NULL
)

Arguments

data

A data frame containing annual erosion and soil measurements.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

erosion_col

Character string. Name of erosion depth column (mm).

bulk_density_col

Character string. Name of bulk density column (g/cm^3). Default bulk density of 1.35 g/cm^3 used if column not found.

slope_col

Optional character string. Name of slope column (percent). Used as a weighting factor.

Details

Soil loss is estimated as:

SL = (erosion\_depth\_mm / 1000) \times bulk\_density \times 10000

where 10000 converts from m^3/m^2 to t/ha assuming bulk density in g/cm^3 equals t/m^3. A slope correction factor of 1 + slope\% / 100 is applied when slope data are available.

Value

A data frame with columns:

year

Year.

field_id

Field identifier.

erosion_depth_mm

Measured erosion depth (mm).

estimated_loss_t_ha

Estimated soil loss (t/ha).

loss_category

Category: "tolerable" (< 5 t/ha/yr), "moderate" (5–10), "severe" (10–20), or "very severe" (> 20).

Examples

data(erosion_profile)
loss <- estimate_soil_loss(erosion_profile, "year", "field_id",
                           "erosion_depth_mm", "bulk_density_g_cm3",
                           slope_col = "slope_pct")
print(loss)

Plot Erosion Depth Trend

Description

Creates a line plot of annual erosion depth over time for each field, with an optional panel showing cumulative erosion loss.

Usage

plot_erosion_trend(
  data,
  year_col,
  field_col,
  erosion_col,
  show_cumulative = FALSE,
  title = NULL
)

Arguments

data

A data frame containing annual erosion measurements.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

erosion_col

Character string. Name of the erosion depth column (mm).

show_cumulative

Logical. Whether to add a second panel showing cumulative erosion (default: FALSE).

title

Optional character string. Plot title.

Value

A ggplot2 object.

Examples

data(erosion_profile)

plot_erosion_trend(erosion_profile, "year", "field_id", "erosion_depth_mm")


Plot Organic Matter Trend

Description

Creates a line plot showing organic matter content (percent) over years for each field, illustrating the effect of tillage management on soil health.

Usage

plot_om_trend(data, year_col, field_col, om_col, title = NULL)

Arguments

data

A data frame containing annual soil measurements.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

om_col

Character string. Name of the organic matter column (percent).

title

Optional character string. Plot title.

Value

A ggplot2 object.

Examples

data(erosion_profile)

plot_om_trend(erosion_profile, "year", "field_id", "organic_matter_pct")


Plot Tillage vs Erosion Comparison

Description

Creates a dual-panel plot showing mean tillage depth alongside erosion depth for each field over time, making the relationship between tillage management and erosion outcomes visually clear.

Usage

plot_tillage_erosion(
  tillage_data,
  erosion_data,
  year_col,
  field_col,
  depth_col,
  erosion_col,
  title = NULL
)

Arguments

tillage_data

A data frame containing tillage operation records.

erosion_data

A data frame containing annual erosion measurements.

year_col

Character string. Name of the year column (must exist in both data frames).

field_col

Character string. Name of the field identifier column (must exist in both data frames).

depth_col

Character string. Name of tillage depth column in tillage_data.

erosion_col

Character string. Name of erosion depth column in erosion_data.

title

Optional character string. Plot title.

Value

A ggplot2 object with two facet panels.

Examples

data(tillage_operations)
data(erosion_profile)

plot_tillage_erosion(tillage_operations, erosion_profile,
                     "year", "field_id", "depth_cm", "erosion_depth_mm")


Plot Tillage Depth Timeline

Description

Creates a line plot showing mean annual tillage depth over time for each field, making it easy to identify shifts toward conservation tillage.

Usage

plot_tillage_timeline(
  data,
  year_col,
  field_col,
  depth_col,
  op_col = NULL,
  title = NULL
)

Arguments

data

A data frame containing tillage operation records.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

depth_col

Character string. Name of the tillage depth column (cm).

op_col

Optional character string. Name of the operation type column.

title

Optional character string. Plot title.

Value

A ggplot2 object.

Examples

data(tillage_operations)

plot_tillage_timeline(tillage_operations, "year", "field_id", "depth_cm")


Summarise Tillage Operations by Year and Field

Description

Computes year-wise summary statistics of tillage depth and operation frequency for each field, including mean depth, maximum depth, total operations, and dominant operation type.

Usage

summarise_tillage(
  data,
  year_col,
  field_col,
  depth_col,
  op_col = NULL,
  validate = TRUE
)

Arguments

data

A data frame containing tillage operation records.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

depth_col

Character string. Name of the tillage depth column (cm).

op_col

Optional character string. Name of the operation type column. If provided, the dominant operation per year-field is included in output.

validate

Logical. Whether to validate inputs before analysis (default: TRUE).

Value

A data frame with one row per year-field combination containing:

year

Year of tillage operations.

field_id

Field identifier.

n_operations

Number of tillage operations performed.

mean_depth_cm

Mean tillage depth (cm).

max_depth_cm

Maximum tillage depth (cm).

total_depth_cm

Cumulative tillage depth (cm).

dominant_operation

Most frequent operation type (if op_col provided).

Examples

data(tillage_operations)
result <- summarise_tillage(tillage_operations, "year", "field_id",
                            "depth_cm", op_col = "operation")
print(result)

Calculate Year-wise Tillage Depth Trend

Description

Computes the annual mean tillage depth per field and calculates the year-on-year change, helping identify whether tillage intensity is increasing, decreasing, or stable over time.

Usage

tillage_depth_trend(data, year_col, field_col, depth_col, validate = TRUE)

Arguments

data

A data frame containing tillage operation records.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

depth_col

Character string. Name of the tillage depth column (cm).

validate

Logical. Whether to validate inputs (default: TRUE).

Value

A data frame with columns:

year

Year.

field_id

Field identifier.

mean_depth_cm

Mean tillage depth for that year (cm).

depth_change_cm

Change in mean depth from previous year (cm). NA for the first year of each field.

trend

Direction of change: "decreasing", "increasing", "stable", or "baseline".

Examples

data(tillage_operations)
trend <- tillage_depth_trend(tillage_operations, "year", "field_id", "depth_cm")
print(trend)

Tillage Operations Dataset

Description

Hypothetical year-wise tillage operation records for two agricultural fields (Field_A and Field_B) over six years (2018–2023). Field_A transitions from conventional deep tillage to conservation tillage, while Field_B follows a reduced tillage practice throughout.

Usage

tillage_operations

Format

A data frame with 20 rows and 6 columns:

year

integer. Calendar year of the tillage operation.

date

Date. Exact date of the tillage operation.

field_id

character. Field identifier: "Field_A" or "Field_B".

operation

character. Type of tillage operation. One of "moldboard_plow", "chisel_plow", "disc_harrow", "conservation_till", or "no_till".

depth_cm

numeric. Tillage depth in centimetres. Zero for no-till operations.

speed_kmh

numeric. Implement operating speed in km/hr. NA for no-till operations.

Details

Field_A represents a field under conventional management that gradually adopts conservation practices: starting with moldboard plowing at 30+ cm depth and transitioning to conservation tillage and no-till by 2022–2023. Field_B maintains reduced tillage (chisel plow and no-till) throughout the study period, serving as a comparison treatment.

This dataset is intended for use with summarise_tillage(), tillage_depth_trend(), and plot_tillage_timeline().

Source

Hypothetical data generated for package illustration purposes.

Examples

data(tillage_operations)

# View structure
str(tillage_operations)

# Summarise by year and field
result <- summarise_tillage(tillage_operations, "year", "field_id", "depth_cm")
print(result)

Track Erosion Depth Over Years

Description

Computes year-on-year change in erosion depth for each field and calculates cumulative erosion since the first recorded year.

Usage

track_erosion_depth(data, year_col, field_col, erosion_col, validate = TRUE)

Arguments

data

A data frame containing annual erosion measurements.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

erosion_col

Character string. Name of the erosion depth column (mm).

validate

Logical. Whether to validate inputs (default: TRUE).

Value

A data frame with columns:

year

Year.

field_id

Field identifier.

erosion_depth_mm

Annual erosion depth (mm).

change_mm

Year-on-year change in erosion depth (mm). NA for the first year of each field.

cumulative_loss_mm

Cumulative erosion depth since first year (mm).

trend

Direction: "improving", "worsening", "stable", or "baseline".

Examples

data(erosion_profile)
result <- track_erosion_depth(erosion_profile, "year", "field_id",
                              "erosion_depth_mm")
print(result)

Validate Tillage or Erosion Input Data

Description

Checks a data frame for common issues before passing it to analysis functions: missing columns, missing values, negative depths, and non-positive years.

Usage

validate_soil_data(data, year_col, field_col, value_col)

Arguments

data

A data frame containing tillage or erosion data.

year_col

Character string. Name of the year column.

field_col

Character string. Name of the field identifier column.

value_col

Character string. Name of the numeric measurement column (depth, soil loss, etc.).

Value

A list with components:

valid

Logical. TRUE if data passed all checks.

issues

Character vector of critical issues found.

warnings

Character vector of non-critical warnings.

Examples

data(tillage_operations)
result <- validate_soil_data(tillage_operations, "year", "field_id", "depth_cm")
print(result$valid)
print(result$warnings)