---
title: "`r params$report_title`"
output: 
  html_document:
    df_print: paged
params:
  scanning_result: NULL
  colnames: NULL
  missing_values_replaced_at: NULL
  constant_data: NULL
  duplicated_rows: NULL
  removed_duplicates: NULL
  duplicates_checked_from: NULL
  out_of_range_dates: NULL
  invalid_subject_ids: NULL
  idx_missing_ids: NULL
  duplicated_ids: NULL
  converted_into_numeric: NULL
  misspelled_values: NULL
  incorrect_date_sequence: NULL
  multi_format_dates: NULL
  report_title: "cleanepi report"
---


```{r cleanepi-setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, comment = NA, rownames.print = FALSE)
```

```{css daiquiri-styles, echo=FALSE}
h1.title {
	font-size: 28px;
	}
p.compact {
	margin-bottom: 0px;
	margin-top: 0px;
	}
```

Report created on: `r Sys.time()` ; cleanepi version `r utils::packageVersion("cleanepi")` ; `r R.Version()$version.string` <img src="`r system.file("extdata", "logo.svg", package = "cleanepi")`" align="right" width="100" height="100"/>

# {.tabset .tabset-pills}

## Source data {.tabset}


```{r cleanepi-source-data, eval=TRUE, echo=FALSE}
# EXTRACT THE REPORT SECTIONS
scanning_result <- params[["scanning_result"]]
is_data_scanned <- !is.na(scanning_result)
standardized_column_names <- params[["colnames"]]
are_column_standardised <- !is.null(standardized_column_names)
out_of_range_dates <- params[["out_of_range_dates"]]
are_out_of_range_dates_found <- !is.null(out_of_range_dates)
incorrect_date_sequence <- params[["incorrect_date_sequence"]]
are_incorrect_date_seq_found <- !is.null(incorrect_date_sequence)
constant_data <- params[["constant_data"]]
are_constant_data_found <- !is.null(constant_data)
duplicated_rows <- params[["duplicated_rows"]]
are_duplicates_found <- !is.null(duplicated_rows)
removed_duplicates <- params[["removed_duplicates"]]
are_duplicates_removed <- !is.null(removed_duplicates)
misspelled_values <- params[["misspelled_values"]]
are_misspelled_values_found <- !is.null(misspelled_values)
missing_values_replaced_at <- params[["missing_values_replaced_at"]]
are_missing_values_replaced <- !is.null(missing_values_replaced_at)
incorrect_subject_id <- params[["invalid_subject_ids"]]
are_incorrect_subject_id <- !is.null(incorrect_subject_id)
missing_ids <- params[["idx_missing_ids"]]
are_missing_ids <- !is.null(missing_ids)
duplicated_ids <- params[["duplicated_ids"]]
are_duplicated_ids <- !is.null(duplicated_ids)
converted_into_numeric <- params[["converted_into_numeric"]]
are_converted_into_numeric <- !is.null(converted_into_numeric)
incorrect_date_sequence <- params[["incorrect_date_sequence"]]
multi_format_dates <- params[["multi_format_dates"]]
are_multi_format_dates <- !is.null(multi_format_dates)
```

### Data structure

```{r scan_data, eval=is_data_scanned}
reactable::reactable( # nolint: cyclocomp_linter
  scanning_result,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    Field_names = reactable::colDef(name  = "field_names",
                                    style = list(fontWeight = "bold",
                                                 fontSize = 15)),
    missing     = reactable::colDef(name  = "missing", align = "center",
                                    style = function(value) {
                                      color      <- "black"
                                      fontWeight <- "normal"
                                      if (value > 0 && value < 1) {
                                        color      <- "orange"
                                        fontWeight <- "bold"
                                      }
                                      return(list(color = color,
                                                  fontWeight = fontWeight))
                                    }),
    numeric     = reactable::colDef(name  = "numeric", align = "center",
                                    style = function(value) {
                                      color      <- "black"
                                      fontWeight <- "normal"
                                      if (value > 0 && value < 1) {
                                        color      <- "orange"
                                        fontWeight <- "bold"
                                      }
                                      return(list(color      = color,
                                             fontWeight = fontWeight))
                                    }),
    date        = reactable::colDef(name  = "date", align = "center",
                                    style = function(value) {
                                      color      <- "black"
                                      fontWeight <- "normal"
                                      if (value > 0 && value < 1) {
                                        color      <- "orange"
                                        fontWeight <- "bold"
                                      }
                                      return(list(color      = color,
                                             fontWeight = fontWeight))
                                    }),
    character   = reactable::colDef(name  = "character", align = "center",
                                    style = function(value) {
                                      color      <- "black"
                                      fontWeight <- "normal"
                                      if (value > 0 && value < 1) {
                                        color      <- "orange"
                                        fontWeight <- "bold"
                                      }
                                      return(list(color      = color,
                                             fontWeight = fontWeight))
                                    }),
    logical     = reactable::colDef(name  = "logical", align = "center",
                                    style = function(value) {
                                      color      <- "black"
                                      fontWeight <- "normal"
                                      if (value > 0 && value < 1) {
                                        color      <- "orange"
                                        fontWeight <- "bold"
                                      }
                                      return(list(color = color,
                                             fontWeight = fontWeight))
                                    })
  )
)
```


### Standardised column names

```{r column_renamed, eval=are_column_standardised}
reactable::reactable(
  standardized_column_names,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  pagination = TRUE,
  rownames   = FALSE,
  compact    = TRUE,
  fullWidth  = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    before = reactable::colDef(name     = "original name",
                               minWidth = 200),
    after  = reactable::colDef(name     = "new name", align = "center",
                               minWidth = 200,
                               style    = list(fontWeight = "bold",
                                               color      = "#008000"))
  )
)
```


### Standardised dates {.tabset}

#### Out of range dates

```{r out_of_range_dates, eval=are_out_of_range_dates_found}
reactable::reactable(
  out_of_range_dates,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    idx = reactable::colDef(name  = "row indices", align = "center",
                            style = list(fontWeight = "normal")),
    column = reactable::colDef(name = "column name", align = "center"),
    original_value = reactable::colDef(name  = "out of range values",
                                       align = "center",
                                       style = list(fontWeight = "bold",
                                                    color      = "#e00000"))
  )
)
```

#### Multi-formatted dates

```{r multi_format_dates, eval=are_multi_format_dates}
multi_format_dates <- multi_format_dates %>%
  dplyr::group_by(field)

reactable::reactable(
  multi_format_dates,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = FALSE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  defaultPageSize = 15,
  columns = list(
    field = reactable::colDef(name = "column name",
      style = htmlwidgets::JS("function(rowInfo, column, state) {
        const firstSorted = state.sorted[0]
        // Merge cells if unsorted or sorting by field
        if (!firstSorted || firstSorted.id === 'field') {
          const prevRow = state.pageRows[rowInfo.viewIndex - 1]
          if (prevRow && rowInfo.values['field'] === prevRow['field']) {
            return { visibility: 'hidden' }
          }
        }
      }")
    ),
    idx = reactable::colDef(name  = "row indices", align = "center",
                            style = list(fontWeight = "normal"))
  ),
  outlined = TRUE
)
```

### Incorrect date sequence

```{r incorrect_date_seq, eval=are_incorrect_date_seq_found}
reactable::reactable(
  incorrect_date_sequence,
  sortable   = FALSE,
  filterable = FALSE,
  searchable = FALSE,
  pagination = TRUE,
  rownames   = FALSE,
  striped    = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  defaultPageSize = 15
)
```

### Duplicates {.tabset}

#### Duplicated rows

```{r duplicates, eval=are_duplicates_found}
duplicated_rows <- duplicated_rows %>% dplyr::relocate(group_id)
reactable::reactable(
  duplicated_rows,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = FALSE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  bordered   = TRUE,
  resizable  = TRUE,
  defaultPageSize = 15,
  outlined = TRUE,
  columns    = list(
    row_id = reactable::colDef(name   = "row indices", align = "center",
                               style  = list(backgroundColor = "#f7f7e7"),
                               sticky = "left"),
    group_id = reactable::colDef(
      name   = "group id", align = "center",
      style = htmlwidgets::JS("function(rowInfo, column, state) {
        const firstSorted = state.sorted[0]
        // Merge cells if unsorted or sorting by group_id
        if (!firstSorted || firstSorted.id === 'group_id') {
          const prevRow = state.pageRows[rowInfo.viewIndex - 1]
          if (prevRow && rowInfo.values['group_id'] === prevRow['group_id']) {
            return { visibility: 'hidden' }
          }
        }
      }"),
      sticky = "left"
    )
  ),
  theme = reactable::reactableTheme(
    borderColor = "#dfe2e5",
    stripedColor = "#f6f8fa",
    highlightColor = "#f0f5f9",
    cellPadding = "8px 12px",
    style = list(
      fontFamily = "-apple-system, BlinkMacSystemFont, Segoe UI,Helvetica, Arial, sans-serif" # nolint: line_length_linter
    ),
    searchInputStyle = list(width = "20%")
  )
)
```

#### Removed duplicates

```{r removed_dups, eval=are_duplicates_removed}
reactable::reactable(
  removed_duplicates,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  bordered   = TRUE,
  resizable  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    row_id = reactable::colDef(name   = "row indices", align = "center",
                               style  = list(backgroundColor = "#f7f7e7"),
                               sticky = "left")
  ),
  theme = reactable::reactableTheme(
    borderColor = "#dfe2e5",
    stripedColor = "#f6f8fa",
    highlightColor = "#f0f5f9",
    cellPadding = "8px 12px",
    style = list(
      fontFamily = "-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif" # nolint: line_length_linter
    ),
    searchInputStyle = list(width = "20%")
  )
)
```

### Constant data

```{r constant_data, eval=are_constant_data_found}
reactable::reactable(
  constant_data,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  bordered   = TRUE,
  resizable  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    iteration = reactable::colDef(name = "iteration", align = "center"),
    empty_columns = reactable::colDef(name = "empty columns", align = "center"),
    empty_rows = reactable::colDef(name = "empty rows", align = "center"),
    constant_columns = reactable::colDef(
      name = "constant columns",
      align = "center"
    )
  )
)
```

### Misspelled values

```{r misspelled_values, eval=are_misspelled_values_found}
reactable::reactable(
  misspelled_values,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  bordered   = TRUE,
  resizable  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    idx = reactable::colDef(name = "row indices", align = "center"),
    column = reactable::colDef(name = "column name", align = "center"),
    value = reactable::colDef(name = "misspelled value", align = "center")
  )
)
```

### Missing value replaced with NA

```{r use_na, eval=are_missing_values_replaced}
missing_values_replaced_at <- data.frame(
  toString(missing_values_replaced_at),
  stringsAsFactors = FALSE
)
names(missing_values_replaced_at) <- "missing values replaced with NA at"
reactable::reactable(
  missing_values_replaced_at,
  sortable   = FALSE,
  filterable = FALSE,
  searchable = FALSE,
  pagination = FALSE,
  rownames   = FALSE,
  striped    = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE
)
```

### Unexpected subject ids {.tabset}

#### Incorrect subject ids

```{r incorrect_ids, eval=are_incorrect_subject_id}
reactable::reactable(
  incorrect_subject_id,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  bordered   = TRUE,
  resizable  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    idx = reactable::colDef(name   = "row indices", align = "center",
                            style  = list(backgroundColor = "#f7f7e7"),
                            sticky = "left"),
    ids = reactable::colDef(name   = "incorrect ids", align = "center",
                            style  = list(backgroundColor = "#f7f7e7"),
                            sticky = "left")
  ),
  theme = reactable::reactableTheme(
    borderColor = "#dfe2e5",
    stripedColor = "#f6f8fa",
    highlightColor = "#f0f5f9",
    cellPadding = "8px 12px",
    style = list(
      fontFamily = "-apple-system, BlinkMacSystemFont, Segoe UI,Helvetica, Arial, sans-serif" # nolint: line_length_linter
    ),
    searchInputStyle = list(width = "20%")
  )
)
```

#### Missing ids

```{r missing_ids, eval=are_missing_ids}
missing_ids <- data.frame(toString(missing_ids), stringsAsFactors = FALSE)
colnames(missing_ids) <- "row indices"
row.names(missing_ids) <- "missing ids"
reactable::reactable(
  missing_ids,
  sortable   = FALSE,
  filterable = FALSE,
  searchable = FALSE,
  pagination = FALSE,
  rownames   = TRUE,
  striped    = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE
)
```

#### Duplicated ids

```{r duplicated_ids, eval=are_duplicated_ids}
reactable::reactable(
  duplicated_ids,
  sortable   = TRUE,
  filterable = FALSE,
  searchable = FALSE,
  rownames   = FALSE,
  pagination = TRUE,
  striped    = TRUE,
  highlight  = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE,
  bordered   = TRUE,
  resizable  = TRUE,
  defaultPageSize = 15,
  columns    = list(
    row_id = reactable::colDef(name   = "row indices", align = "center",
                               style  = list(backgroundColor = "#f7f7e7"),
                               sticky = "left"),
    group_id = reactable::colDef(name   = "group id", align = "center",
                                 style  = list(backgroundColor = "#f7f7e7"),
                                 sticky = "left")
  ),
  theme = reactable::reactableTheme(
    borderColor = "#dfe2e5",
    stripedColor = "#f6f8fa",
    highlightColor = "#f0f5f9",
    cellPadding = "8px 12px",
    style = list(
      fontFamily = "-apple-system, BlinkMacSystemFont, Segoe UI,Helvetica, Arial, sans-serif" # nolint: line_length_linter
    ),
    searchInputStyle = list(width = "20%")
  )
)
```

### Columns converted into numeric {.tabset}

```{r cols_converted_to_num, eval=are_converted_into_numeric}
converted_into_numeric <- data.frame(
  toString(converted_into_numeric),
  stringsAsFactors = FALSE
)
names(converted_into_numeric) <- "columns converted into numeric"
reactable::reactable(
  converted_into_numeric,
  sortable   = FALSE,
  filterable = FALSE,
  searchable = FALSE,
  pagination = FALSE,
  rownames   = FALSE,
  striped    = TRUE,
  compact    = TRUE,
  fullWidth  = TRUE
)
```

## Aggregated data {.tabset}
