--- title: "Import your data" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Import your data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` You can immediately install {soils}, create a new template project, and render example reports, as demonstrated in the last two tutorials. However, you will need to customize and edit the content to fit your project, shown in the next three tutorials: [**Customize & write**](https://wa-department-of-agriculture.github.io/soils/articles/customize.html), [**Render reports**](https://wa-department-of-agriculture.github.io/soils/articles/render.html), and [**Troubleshoot**](https://wa-department-of-agriculture.github.io/soils/articles/troubleshoot.html). ## Access the example datasets An example dataset and data dictionary are included in every {soils} project. Access the `.csv` files in the `data` folder, or load the package and call the dataframes by name as shown below.
Load {soils} and see first five rows of each dataframe ```{r} library(soils) head(washi_data, 5) |> knitr::kable() head(data_dictionary, 5) |> knitr::kable() ```
Use `washi_data` and `data_dictionary` as templates when formatting your own data to use in {soils} functions and reports. ## Data template Your data must contain the below required columns and each soil measurement must be in its own column, as shown in `washi_data`.
Glimpse at the example data ```{r} dplyr::glimpse(washi_data) ```
Your data **must have the below required columns**. However, only the columns in **bold** are required to have values. Put another way, your data must have these column names, even if every row is blank. Otherwise, the `data-validation` chunk in `01_producer-report.qmd` or {soils} functions will error. For more details, see [Data/dictionary mismatches]. - **`year `** is used to select samples to be included in the report. - **`sample_id `** must be unique throughout the dataset. - `farm_name ` is included at the top of the report. If blank, it is replaced with "Farm: `producer_id`". - **`producer_id `** is used to select samples to be included in the report. - `field_name ` must be unique across all fields for each producer and is displayed in tables and tool tips for maps. If blank, it is replaced with "Field `field_id`". - **`field_id `** must be unique across all fields for each producer. - `county ` is used to group and summarize samples from the same county as the producer. Can be blank. - `crop ` is used to group and summarize samples from the same crop as the producer. Can be blank. - `longitude ` and `latitude ` are used to map each sample point using the [{leaflet}](https://rstudio.github.io/leaflet/index.html) package. Coordinates must be in decimal degrees using WGS 84 (aka EPSG:4326). If blank, the map will not be included. - **`texture `** is used in the "physical" measurement group table. This column is not used in the texture triangle plot, which is instead created from percentage sand, silt, and clay measurement results. - **Each soil measurement** must have its own column in the dataset and a corresponding row in the data dictionary, as shown in [Dictionary template]. - Measurement columns come **after** the required columns for easy selection in the [`tidy-long` chunk]. ## Dictionary template The data dictionary is used to group and order soil measurements, and to nicely format labels in tables and plots. The example `data_dictionary` contains [UTF-8](https://www.unicode.org/faq/utf_bom.html) encoded superscripts, subscripts, and special characters. To properly encode your data dictionary as UTF-8, save it to the `data` folder as `CSV UTF-8 (Comma delimited) (*.csv)` in MS Excel. ![](../man/figures/utf-8.png){fig-alt="Data dictionary is saved as CSV UTF-8 (Comma delimited) (*.csv) in MS Excel."}
Glimpse at the example data dictionary ```{r} dplyr::glimpse(data_dictionary) ```
Your data dictionary **must have the below required columns** for every soil measurement included in your data. - **`measurement_group `** determines how the soil measurements are grouped. The order in which these groups appear in the report is determined by the order they are listed within the data dictionary. - **`column_name `** is used to join the dictionary with your data. Must exactly match the column names of the soil measurements in your dataset. The order in which these measurements appear within their `measurement_group` is determined by the order they are listed within the data dictionary. - **`abbr `** and **`unit `** are how soil measurements are labeled in tables with the abbreviation as the column header and unit as a secondary spanning header. ## Data/dictionary mismatches Getting your data and dictionary in the proper format to render the report without errors will likely be the most difficult part of making {soils} work for your project. The [`data-validation` chunk] and many {soils} functions include `testthat::expect_contains()` to fail early if required columns are missing from either the data or the dictionary. This early failure saves time by stopping as soon as the missing column or data/dictionary mismatch is identified. Additionally, these early failed tests provide the `expected` versus `actual` values, making it easier to correct the issue with minimal debugging. Below are some common issues that arise and possible workarounds. These workarounds may make more sense after reviewing the [Your data] section that includes example errors and fixes. ### Extra columns in data **Soil measurements in your data but not in your dictionary** will cause the report to error in the `data-validation` chunk. For example, rendering the report will fail if your dataset contains both `pH` and `CEC` results but your dictionary only contains `pH`. Either add the `CEC` measurement to your dictionary or remove this measurement column from your data. If you don't want to delete the column from your datasheet, you can remove it from only the data object with `data <- dplyr::select(data, -cec_meq_100g)` perhaps in the `load-data` chunk. **Additional metadata columns in your data** will also cause the report to error in the `data-validation` chunk. For example, if you have a column `phone_number` with producer phone numbers that won't be used in the report, remove it from the data with the `data <- dplyr::select(data, -c(cec_meq_100g, phone_number))`. If you want to use this column in the report, then add it to the `required_cols` vector of the [`data-validation` chunk] so that the `testthat` function doesn't error. ### Extra rows in dictionary **Soil measurements in your dictionary but not in your data** will not error and will not affect the report. For example, the report will simply show the `pH` results if your dictionary contains both `pH` and `CEC` but your data only contains `pH` results. ## Your data Once your project data and dictionary files match the structure of the examples and are saved in the `data` folder, follow along with the changes in the code chunks in `01_producer-report.qmd`. Code you will need to change are marked with the text "`EDIT:`". Find all edit markers in the RStudio project with `Ctrl` + `Shift` + `F` to open the `Find in Files` wizard. Below changes are for demonstration purposes only, the actual changes should be based on **your** data and dictionary. ### `load-data` chunk Replace `washi-data.csv` with the name of your data file (`my-data.csv`).
Example changed chunk ```{r load-data, eval=FALSE} # EDIT: Add your cleaned lab data to the data folder, using 'washi-data.csv' as # a template. # Load lab results data <- read.csv( here::here("data/my-data.csv"), check.names = FALSE, encoding = "UTF-8", strip.white = TRUE ) ```
### `load-dictionary` chunk Change `data-dictionary.csv` to the name of your dictionary file (`my-dictionary.csv`). If using subscripts, superscripts, or special characters, make sure your csv is saved with UTF-8 encoding (see [Dictionary template] for how to do this).
Example changed chunk ```{r load-dictionary, eval=FALSE} # EDIT: Add your data dictionary to the data folder, using 'data-dictionary.csv' # as a template. # Load data dictionary dictionary <- read.csv( here::here("data/my-dictionary.csv"), check.names = FALSE, # Set encoding for using subscripts, superscripts, special characters encoding = "UTF-8", strip.white = TRUE ) ```
### `tidy-long` chunk Replace the column range of the soil measurements from the example `washi-data.csv` (`12:42`) with the column range of the soil measurements in your data (`12:26`). This chunk [tidies the data](https://vita.had.co.nz/papers/tidy-data.pdf) from wide to long for summarization and visualization.
Example changed chunk ```{r tidy-long, eval=FALSE} # EDIT: `washi_data` example has soil measurements in columns 12 - 42. Replace # this column range with the column indices of the soil measurements in your # dataset. # Tidy data into long format and join with data dictionary results_long <- data |> dplyr::mutate( dplyr::across( # EDIT: replace with the column range of your soil measurements 12:26, as.numeric ) ) |> tidyr::pivot_longer( # EDIT: replace with the column range of your soil measurements cols = 12:26, names_to = "measurement" ) ```
### `data-validation` chunk This chunk checks there are no mismatches as described in [Data/dictionary mismatches] by making sure all column names in your dataset are in either the `required_cols` vector or the `column_name` column of `my-dictionary.csv`. In this example, add an extra column named `tillage` in `my-data.csv` without changing the dictionary. After clicking the `Render` button, the report failed. ``` r Quitting from lines 94-115 [data-validation] (01_producer-report.qmd) Error: ! names(data) (`actual`) isn't fully contained within c(required_cols, dictionary$column_name) (`expected`). * Missing from `expected`: "tillage" * Present in `expected`: "year", "sample_id", "farm_name", "producer_id", "field_name", "field_id", "county", "crop", "longitude", ... ``` This error message says the error occurred in lines 94-115 in the `data-validation` chunk because `tillage` was missing from the `expected` values, which are elements of `required_cols` and `dictionary$column_name`. Adding `"tillage"` to `required_cols` prevents this error.
Example changed chunk ```{r data-validation-changed, eval=FALSE} # OPTIONAL EDIT: If you have extra columns in `data`, add them to this vector. required_cols <- c( "year", "sample_id", "farm_name", "producer_id", "field_name", "field_id", "county", "crop", "longitude", "latitude", "texture", "tillage" ) # Check all column names in `data` are in the `required_cols` vector or # `column_name` column of `dictionary`. testthat::expect_in(names(data), c(required_cols, dictionary$column_name)) ```
To demonstrate another data/dictionary mismatch error, remove `cec_meq_100g` from the dictionary while keeping it in the dataset. ``` r Quitting from lines 94-115 [data-validation] (01_producer-report.qmd) Error: ! names(data) (`actual`) isn't fully contained within c(...) (`expected`). * Missing from `expected`: "cec_meq_100g" * Present in `expected`: "year", "sample_id", "farm_name", "producer_id", "field_name", "field_id", "county", "crop", "texture", ... ``` The error occurred because `cec_meq_100g` was missing from the `expected` values. Either add `cec_meq_100g` back to the dictionary or remove this column from the dataset to fix this error. **See the [troubleshooting article](https://wa-department-of-agriculture.github.io/soils/articles/troubleshoot.html) for more help on debugging errors.** article]() for more help on debugging errors.\*\*