--- title: "Table Dialect" author: "Peter Desmet" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Table Dialect} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` [Table Dialect](https://datapackage.org/standard/table-dialect/) is a simple format to describe the dialect of a tabular data file, including its delimiter, header rows, escape characters, etc. ::: {.callout-note} In this document we use the terms "package" for Data Package, "resource" for Data Resource, "dialect" for Table Dialect, and "schema" for Table Schema. ::: ## General implementation frictionless supports most dialect properties to read [Tabular Data Resources](https://datapackage.org/standard/data-resource/#tabular), but only those designed for [delimited formats](https://datapackage.org/standard/table-dialect/#delimited) (not structured, spreadsheet, database formats). Dialect manipulation is limited to setting a `delimiter`. When writing resources, it (mainly) makes use of default dialect properties, removing the necessity to define them. ### Read `read_resource()` uses the `dialect` property of a resource to parse a tabular data file. Only properties that deviate from the default need to be specified. E.g. a tab-delimited file without header rows must have the following dialect: ```json "dialect": { "delimiter": "\t", "header": false } ``` ### Manipulate A dialect is a list you can manipulate, but that is typically not necessary. `add_resource()` sets one property (`delimiter`) when data are provided as a CSV file with non-default delimiter, all other properties are assumed to be the default. `add_properties()` can be used to add (custom) metadata properties to a dialect. ### Write `write_package()` writes a package to disk as a `datapackage.json` file. This file includes the metadata of all the resources, including the dialect (if defined). `write_package()` writes resources created from a data frame to CSV files, but no `dialect` property is set for those, since only defaults are used. ## Properties implementation ### $schema [`$schema`](https://datapackage.org/standard/table-dialect/#dollar-schema) indicates what `version()` of the Table Dialect standard is used (v1 if undefined). - `read_resource()` ignores it and does not upgrade a dialect, since it does not rely on v1 properties deprecated in v2. - `add_resource()` does _not_ set `$schema` to the recommended v2 value (`"https://datapackage.org/profiles/2.0/tabledialect.json"`), because it typically does not define a dialect and therefore `$schema`. It thus creates (default to) a v1 dialect. - `upgrade_package()` leaves the dialect as is for all resources. ### header [`header`](https://datapackage.org/standard/table-dialect/#header) is used by `read_resource()` and defaults to `true`. It is passed as `skip = 1` (or `0` for `false`) in `readr::read_delim()`, ignoring the header. Field names in `schema` are used instead. ### headerRows [`headerRows`](https://datapackage.org/standard/table-dialect/#headerRows) is **not supported** by `read_resource()`. ### headerJoin [`headerJoin`](https://datapackage.org/standard/table-dialect/#headerJoin) is **not supported** by `read_resource()`. ### commentRows [`commentRows`](https://datapackage.org/standard/table-dialect/#commentRows) is **not supported** by `read_resource()`. ### commentChar [`commentChar`](https://datapackage.org/standard/table-dialect/#commentChar) is used by `read_resource()` and defaults to undefined. It is passed to `comment` in `readr::read_delim()`. ### delimiter [`delimiter`](https://datapackage.org/standard/table-dialect/#delimiter) is used by `read_resource()` and defaults to `","`. It is passed to `delim` in `readr::read_delim()`. `add_resource()` does not set `delimiter`, unless provided in `delim` and different from the default `","`: ```{r} library(frictionless) package <- example_package() path <- system.file("extdata", "v2", "observations_1.tsv", package = "frictionless") package <- add_resource(package, "observations", data = path, delim = "\t", replace = TRUE) resource(package, "observations")$dialect$delimiter ``` ### lineTerminator [`lineTerminator`](https://datapackage.org/standard/table-dialect/#lineTerminator) is **not supported** by `read_resource()`. It relies on `readr::read_delim()` instead, which interprets line terminator `LF` and `CRLF` automatically and does not support `CR` (used by Classic Mac OS, final release 2001). ### quoteChar [`quoteChar`](https://datapackage.org/standard/table-dialect/#quoteChar) is used by `read_resource()` and defaults to `"`. It is passed to `quote` in `readr::read_delim()`. ### doubleQuote [`doubleQuote`](https://datapackage.org/standard/table-dialect/#doubleQuote) is used by `read_resource()` and defaults to `true`, but can be overruled by `escapeChar`. It is passed to `escape_double` in `readr::read_delim()`. ### escapeChar [`escapeChar`](https://datapackage.org/standard/table-dialect/#escapeChar) is **not supported** by `read_resource()` unless it is `"\\"`. It is passed as `escape_backslash = TRUE` and `escape_double = FALSE` in `readr::read_delim()`. ::: {.callout-warning} `escapeChar` and `doubleQuote` are mutually exclusive, so you cannot escape with `\"` and `""` in the same file. ::: ### nullSequence [`nullSequence`](https://datapackage.org/standard/table-dialect/#nullSequence) is **not supported** by `read_resource()`. Provide as `missingValues` in the schema instead (see `vignette("table-schema")`). ### skipInitialSpace [`skipInitialSpace`](https://datapackage.org/standard/table-dialect/#skipInitialSpace) is used by `read_resource()` and defaults to `false`. It is passed to `trim_ws` in `readr::read_delim()`.