--- title: "Introduction to yaml" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to yaml} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(yaml) ``` ## What is YAML? YAML is a human-readable data serialization language. With it, you can create easily readable documents that can be consumed by a variety of programming languages. For example, here's a map of baseball teams per league: ```yaml american: - Boston Red Sox - Detroit Tigers - New York Yankees national: - New York Mets - Chicago Cubs - Atlanta Braves ``` And a data dictionary specification: ```yaml - field: ID description: primary identifier type: integer primary key: yes - field: DOB description: date of birth type: date format: yyyy-mm-dd - field: State description: state of residence type: string ``` ## Parsing YAML `yaml.load()` parses a YAML document from a string: ```{r} yaml.load(" - 1 - 2 - 3 ") ``` `yaml.load_file()` and `read_yaml()` read YAML from a file or connection. ### Scalars A YAML scalar is the basic building block of YAML documents. The parser automatically determines the type: ```{r} yaml.load("1.2345") yaml.load("true") yaml.load("hello") ``` ### Sequences A YAML sequence is a list of elements. If all elements are uniform, `yaml.load()` returns a vector of that type. Otherwise, it returns a list: ```{r} # Uniform sequence -> vector yaml.load(" - 1 - 2 - 3 ") # Mixed sequence -> list yaml.load(" - 1 - hello - true ") ``` ### Maps A YAML map is a list of paired keys and values. By default, `yaml.load()` returns a named list: ```{r} yaml.load(" one: 1 two: 2 three: 3 ") ``` Since YAML map keys can be almost anything (not just strings), you can preserve the data type of keys with `as.named.list = FALSE`. This creates a `keys` attribute instead of coercing keys to strings: ```{r} yaml.load(" 1: one 2: two ", as.named.list = FALSE) ``` ### Custom handlers You can customize parsing with handler functions. Handlers are passed to `yaml.load()` as a named list, where each name is the YAML type to handle: ```{r} # Add 100 to all integers yaml.load("123", handlers = list(int = function(x) as.integer(x) + 100)) ``` #### Sequence handlers Sequence handlers receive a list and can transform it: ```{r} yaml.load(" - 1 - 2 - 3 ", handlers = list(seq = function(x) sum(as.numeric(x)))) ``` #### Map handlers Map handlers receive a named list (or a list with a `keys` attribute): ```{r} yaml.load(" a: - 1 - 2 b: - 3 - 4 ", handlers = list(map = function(x) as.data.frame(x))) ``` ## Emitting YAML `as.yaml()` converts R objects to YAML strings: ```{r} cat(as.yaml(1:5)) ``` `write_yaml()` writes the result directly to a file or connection. ### Formatting options #### indent Control indentation depth (default is 2): ```{r} cat(as.yaml(list(foo = list(bar = "baz")), indent = 4)) ``` #### indent.mapping.sequence By default, sequences within a mapping are not indented: ```{r} cat(as.yaml(list(foo = 1:3))) ``` Set `indent.mapping.sequence = TRUE` to indent them: ```{r} cat(as.yaml(list(foo = 1:3), indent.mapping.sequence = TRUE)) ``` #### column.major Controls how data frames are converted. When `TRUE` (default), data frames are emitted column-wise: ```{r} x <- data.frame(a = 1:2, b = 3:4) cat(as.yaml(x, column.major = TRUE)) ``` When `FALSE`, data frames are emitted row-wise: ```{r} cat(as.yaml(x, column.major = FALSE)) ``` ### Custom handlers Specify custom handler functions for R object classes: ```{r} cat(as.yaml( Sys.Date(), handlers = list(Date = function(x) format(x, "%Y/%m/%d")) )) ``` ### YAML 1.2 logical handling For YAML 1.2-like logical output, use `verbatim_logical`: ```{r} cat(as.yaml(c(TRUE, FALSE), handlers = list(logical = verbatim_logical))) ``` ### Verbatim text Character vectors with class `"verbatim"` are not quoted except when required by the YAML specification: ```{r} result <- c("true", "false") class(result) <- "verbatim" cat(as.yaml(result)) ``` ### Quoted strings Force quoting with the `"quoted"` attribute: ```{r} port <- "80:80" attr(port, "quoted") <- TRUE cat(as.yaml(list(ports = list(port)))) ``` ### Custom tags Set YAML tags with the `"tag"` attribute: ```{r} x <- 1:3 attr(x, "tag") <- "!custom" cat(as.yaml(x)) ```