---
title: "Get started with washr"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Get started with washr}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = FALSE
)
```

washr turns a cleaned dataset into a documented R data package that follows the FAIR principles, with a website, a citation file and machine readable metadata. This page walks through the workflow in the order you run it. Each step is one function, and every function is safe to run again after you have edited the files it wrote.

The [FAIR Data Publishing guide](https://openwashdata.github.io/fair-publishing/) covers the same steps with more explanation and the parts that happen outside R, such as creating the GitHub repository and the Zenodo release. The chapters of the guide follow the same order as the sections below.

## Install

The stable release, from CRAN:

```{r}
install.packages("washr")
```

The current development build, from the [openwashdata R-universe](https://openwashdata.r-universe.dev). It is rebuilt on every push and installs like any other package, with no compiler toolchain:

```{r}
install.packages("washr", repos = c("https://openwashdata.r-universe.dev", getOption("repos")))
```

The same development source from GitHub, built on your machine:

```{r}
# install.packages("remotes")
remotes::install_github("openwashdata/washr")
```

## 1. Create the package

Create an R package for the dataset and open it as a project. The package name is the name of the dataset, in lower case, without dots or underscores.

```{r}
usethis::create_package("~/path/to/fslogisticskampala")
```

Then put it under version control and on GitHub, for example with `usethis::use_git()` and `usethis::use_github()`. The guide describes this step in detail.

`setup_ci()` adds the GitHub Actions workflow that runs `R CMD check` on every push and pull request, on macOS, Windows and three versions of R on Linux. The openwashdata review standard requires it, so run it now and the package meets that part of the standard from its first commit.

```{r}
library(washr)
setup_ci()
```

## 2. Bring in the raw data

Run `setup_rawdata()` from the package root. It creates `data-raw/` and a processing script, `data-raw/data_processing.R`, with the steps the script should follow.

```{r}
setup_rawdata()
```

Copy the raw files into `data-raw/`. In the processing script, read them, clean them into one or more tidy data frames, and end with `usethis::use_data()` so each data frame lands in `data/` as an `.rda` file. The script also exports each data frame as CSV and XLSX into `inst/extdata/`, which is where the website and the metadata find the downloadable files.

## 3. Write the dictionary

`setup_dictionary()` reads every data object in `data/` and writes `data-raw/dictionary.csv` with one row per variable: the file it belongs to, its name, its type, and an empty description.

```{r}
setup_dictionary()
```

Open the CSV and write a description for every variable. The dictionary is the one place where variables are described; the roxygen documentation and the metadata are generated from it.

When the data changes later, run `update_dictionary()`. It adds a row for each new variable, removes the row of a variable that no longer exists, refreshes the types, and keeps every description and every column you added yourself, such as `unit` or `allowed_values`. Then run `setup_roxygen()` again.

```{r}
update_dictionary()
```

## 4. Generate the roxygen documentation

`setup_roxygen()` writes one file per data object under `R/`, with a title and description placeholder and the variable table from the dictionary.

```{r}
setup_roxygen()
```

Open each file, replace the title and the description, then run `devtools::document()` so the help pages exist. When you change a description in the dictionary later, run `setup_roxygen()` again: it regenerates only the variable table and keeps the title, the description and anything else you wrote in the file.

## 5. Complete DESCRIPTION

`update_description()` sets the fields the openwashdata standard expects: the language, the date, the repository URL, the bug report URL, and the CC BY 4.0 license when the package has none yet. Existing values are kept and merged. It also writes a few `Config/washr/` fields, such as the funding sentence and the analytics domain of the site. The later steps read them from `DESCRIPTION`, and the last section of this page explains them.

```{r}
update_description()
```

Then open `DESCRIPTION` and check the title, the description and the authors. Authors are written with `person()` and carry their ORCID in the comment field. Three more facts have no other home and go into `DESCRIPTION` by hand:

```
X-schema.org-keywords: sanitation, faecal sludge, Kampala
X-schema.org-spatialCoverage: Kampala, Uganda
X-schema.org-temporalCoverage: 2022-03-01/2022-09-30
```

The keywords are a comma separated list. The spatial coverage is a place name. The temporal coverage is a start and an end date separated by a slash.

## 6. Generate the metadata

`update_metadata()` derives a schema.org description of the dataset from `DESCRIPTION`, the dictionary, the citation file and the files in `inst/extdata`, and writes it as JSON-LD into `pkgdown/templates/in-header.html`. The website build embeds it in the head of every page, where dataset search engines read it.

```{r}
update_metadata()
```

The function ends with the fields it could not fill and where to fill them. Nothing is edited by hand: change the source and run it again. This function is experimental; its output shape may still change.

## 7. Write the README

`setup_readme()` writes `README.Rmd` from the openwashdata template, with the installation instructions, the download table, and a section for the first data object. With `has_example = TRUE` it adds an Example section with a scaffold for a first plot.

```{r}
setup_readme(has_example = TRUE)
```

Write the text, add a section for each further data object, then render it:

```{r}
devtools::build_readme()
```

## 8. Build the website

`setup_website()` writes `_pkgdown.yml` from the openwashdata template and builds the site into `docs/`. The template sets the Pages URL, the analytics header, the funding sidebar, and a reference index with one entry per data object.

```{r}
setup_website()
```

Running it again keeps your `_pkgdown.yml` and rebuilds the site. `docs/` is committed and served by GitHub Pages; when the package deploys through a pkgdown GitHub Actions workflow instead, the function leaves `docs/` ignored.

`use_brand()` installs the openwashdata brand, the fonts and colors of the site, from the latest release of the central brand repository and wires `_pkgdown.yml` to it. It records the release it installed in `DESCRIPTION` as `Config/washr/brand`. Run it once after `setup_website()`, and again after a new brand release; a run with no new release changes nothing.

```{r}
use_brand()
```

Branded PDF and Word reports about the package use the openwashdata Quarto extension, [quarto-owd](https://github.com/openwashdata/quarto-owd), with the formats `owd-typst` and `owd-docx`. Install it in the package root with `quarto add openwashdata/quarto-owd`; it reads the `_brand.yml` that `use_brand()` installed, so no second brand copy is needed. Add `^_extensions$` to `.Rbuildignore`.

## 9. Cite and release

`update_citation()` writes `CITATION.cff` and `inst/CITATION` from `DESCRIPTION`. Run it before the first release so the files exist, then again with the DOI once the release is deposited on Zenodo; the guide describes the Zenodo steps.

```{r}
update_citation()
```

Before you create the release, run `check_publication_readiness()`. It reads the package and reports, item by item, what is in place and what is missing, and for every gap it names the step that closes it. It writes nothing, so run it as often as you like.

```{r}
check_publication_readiness()
```

After the Zenodo release, run `update_citation()` once more with the DOI:

```{r}
update_citation(doi = "10.5281/zenodo.11185699")
```

With a DOI the function also adds the DOI badge to the README and rebuilds it and the site. A later run without the DOI keeps the DOI on file. Run `update_metadata()` once more after that, so the metadata carries the DOI as well.

The same call writes `.zenodo.json` from `DESCRIPTION`. Zenodo reads this file when it archives a GitHub release and takes the resource type (Dataset), the community, the creators and the license from it. Commit the file before you create the release. `update_zenodo_json()` writes it on its own.

## Running steps again

Every function above reads what is there, merges its changes, and writes only what changed. The two exceptions stop instead of overwriting: `setup_dictionary()` when the dictionary exists (run `update_dictionary()` instead, which keeps what you wrote), and `setup_readme()` when `README.Rmd` exists (pass `force = TRUE` to replace it). A full second run of the other steps on an unchanged package changes no file.

## More than one dataset

The processing script and the README template are written for one dataset that carries the name of the package. A package can hold more. In `data-raw/data_processing.R`, repeat the export block for each data frame, so each one is saved with `usethis::use_data()` and exported to `inst/extdata/`. `setup_dictionary()`, `setup_roxygen()`, `setup_website()` and `update_metadata()` cover every data object in `data/` on their own. `setup_readme()` documents the first one, so add a section per further data object to `README.Rmd` by hand.

## Publishing outside openwashdata

washr ships with the openwashdata values as defaults, and every one of them lives in `DESCRIPTION`, so another group publishes with its own values by editing that file. Nothing else has to change.

Start by naming your GitHub organisation, once:

```{r}
update_description(github_user = "https://github.com/yourorg")
```

From then on the organisation, the repository URL, the license and the people are read from the standard `DESCRIPTION` fields (`URL`, `License`, `Authors@R`), and the README, the site, the citation files and the metadata follow them. The values that have no standard field are the `Config/washr/` fields:

| Field | What it sets | Value for another group |
|---|---|---|
| `Config/washr/funding` | the funding sentence in the sidebar of the site | your funding sentence, Markdown allowed, or `none` |
| `Config/washr/analytics-domain` | the Plausible analytics header of the site | your Plausible domain, or `none` |
| `Config/washr/doi-provider` | the DOI badge of the README | `zenodo`, or the name of another provider for a generic DOI badge |
| `Config/washr/zenodo-community` | the community in `.zenodo.json` | your Zenodo community, or `none` |
| `Config/washr/brand-source` | the repository `use_brand()` copies from | the GitHub repository of your brand, such as `yourorg/brand`, or `none` |
| `Config/washr/pages-domain` | the domain of the site | only when the site is not served from `yourorg.github.io` |

For a package under another organisation, `update_description()` writes the funding, analytics, community and brand fields as `none` and lists them, because the openwashdata values would be wrong there. Edit them, then run the steps as above. A field that is set is never overwritten. `check_publication_readiness()` holds the package to these values.

A license other than CC BY 4.0 is set in `License` before the first `update_description()`, for example with `usethis::use_cc0_license()` or another `usethis::use_*_license()` function. `update_description()` leaves a license that is set as it is.
