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

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 8,
                      fig.height = 4.5, dpi = 120)
library(datagrade)
```

## One call

`dg_assess()` takes a data frame or a file path and returns a `dg_report`
object. Nothing is written to the global environment, and the data frame you
pass in is never modified.

```{r}
report <- dg_assess(iris, verbose = FALSE)
report
```

## The object, not the printout

The reference implementation this package grew out of printed everything with
`cat()` and returned `NULL`, so nothing could be used programmatically. Here the
printout is a side effect and the object is the product.

```{r}
report$scores
report$measures[, c("code", "characteristic", "value", "a", "b")]
report$outliers$by_column
report$redundancy$pairs
```

Each measure is a ratio `A / B`: `A` counts the data items satisfying the
property, `B` the items for which the property is defined at all. A measure with
`b = NA` is not a failing measure -- it is one whose denominator could not be
counted, because nobody has said what the data is supposed to look like yet.

## Declaring what the data should look like

Six of the fifteen properties are computable from the table alone. The other
nine compare the data against an expectation, and an expectation is declared,
not discovered. `dg_spec()` is where it goes; every argument is optional and
each one switches on the measures that depend on it.

```{r}
spec <- dg_spec(
  required = c("Sepal.Length", "Species"),
  ranges   = list(Sepal.Length = c(4, 8), Petal.Width = c(0, 3)),
  domains  = list(Species = levels(iris$Species)),
  rules    = list(petal_smaller = ~ Petal.Length < Sepal.Length)
)
spec
```

```{r}
scored <- dg_assess(iris, spec = spec, verbose = FALSE)
scored$scores
scored$measures[scored$measures$applicable,
                c("code", "value", "a", "b")]
```

Accuracy is now measurable, where without a spec it was `NA`. The `note` column
says what each remaining measure is still waiting for:

```{r}
waiting <- scored$measures[!scored$measures$applicable, c("code", "note")]
waiting
```

## Plausibility is not accuracy

One number sits outside the model deliberately. `plausibility` flags outliers
against an interval *derived* from the data, where every ISO accuracy property
needs one that was *declared*. An outlier need not be wrong, and a wrong value
can sit exactly on the mean -- so it is reported separately and left out of the
overall score.

```{r}
report$plausibility
report$scores[["accuracy"]]   # NA: nothing was declared
```

It is still the most useful single number in the report for data that arrives
with no documentation, which is most open data.

`summary()` gives the same content as tables:

```{r}
summary(report)$columns
```

## Assessing many data sets at once

`as.data.frame()` collapses a report to one row, which is what makes a corpus
sweep a two-liner:

```{r}
datasets <- list(iris = iris, mtcars = mtcars, airquality = airquality)
sweep <- do.call(rbind, lapply(names(datasets), function(nm) {
  row <- as.data.frame(dg_assess(datasets[[nm]], verbose = FALSE))
  row$source <- nm
  row
}))
sweep[, c("source", "rows", "completeness", "consistency", "overall",
          "plausibility")]
```

## Figures

`dg_plots()` returns a named list of ggplot objects. Every figure is built from
statistics computed during the assessment, so the plot objects never carry the
raw observations.

```{r}
figures <- dg_plots(report)
names(figures)
figures$scores
```

```{r}
figures$correlation
```

```{r, fig.height = 5.5}
figures$distribution
```

Use `dg_save_plots(report, "figures/")` to write them all to disk.

## Reading from a file

```{r}
path <- tempfile(fileext = ".csv")
write.csv(mtcars, path, row.names = FALSE)
dg_assess(path = path, verbose = FALSE)$scores
unlink(path)
```

`.csv`, `.tsv` and `.txt` are read with base R. `.xls` and `.xlsx` need the
suggested **readxl** package.

## Helpers stand alone

Each of the checks is exported and usable on its own:

```{r}
detect_data_types(data.frame(id = c("a", "b", "c"), n = c(1.5, 2.5, 3.5)))
dg_vif(iris)
analyze_distribution(iris)
```

## Where to next

* `vignette("methodology")` -- every formula, and how each score is computed.
* `vignette("scalability")` -- measured behaviour from 54 thousand to 10 million rows.
* `vignette("deviations")` -- how this package differs from the dissertation it implements, and why.
