-
Notifications
You must be signed in to change notification settings - Fork 15
Native input specification
DISCLAIMER
This document is for developers' reference only and/or for a pair of curious eyes who'd like an early-bird preview of new input specifications and rapport's course of development. Feel free to rant if you think that something we're working on is pure rubbish.
Rationale: old inputs suck because they differ from native R classes. Instead of rolling our own inventions, why not embrace the (implicit) conventions from R ecosystem and build/define inputs according to them? Writing templates should be straightforward and rapport should make you warm and fuzzy inside.
Native input specification takes leverage of R objects' classes, thus not relying on custom conventions when defining template inputs. Following specifications are to depict the current state of implementation along with conventions used in it. Unlike old input specification that relied on rather cumbersome custom syntax, new input specification is 100% pure YAML, and as such should be more intuitive and native to R.
Inputs can be divided into two categories:
-
dataset inputs (non-standalone) - inputs that match the named element in the object provided in
dataformal argument inrapportcall. This is usually adata.frameobject, but can/should be any object that allows subsetting by name, i.e. that has named elements (namedlistwill do). Dataset inputs cannot have the (default) value, so they always require user input. -
standalone inputs don't depend on object passed in
data. They accept object provided invalueattribute in the template definition, and users can provide their own as well by passing an object of an appropriateclassin therapportcall.
Following options are available for all inputs:
-
name(character string) - input name. Cannot be blank, as mapped inputs will be assigned to that name in the evaluation environment. Custom naming conventions (compatible with R ones) are applied - see?rapport:::guess.input.namefor details. #change this to user-friendly man page (e.g. Rapport naming conventions or smth -
label(character string) - input label. Can be blank, but it's useful to have something in there in order to get pretty output in a report, e.g. in plots and tables (e.g.Number of hoursis by far more descriptive thannwhours). Defaults to empty string. -
description(character string) - input description. It can be blank, but sometimes it's convenient to have a lengthy description of provided input. Defaults to empty string. -
class(character string) - defines aclassof an input (d'uh). It can be omitted (defaults toany), but most of the times you'll find it useful to fine-tune your inputs. Currently supported classes are:any(default),character,complex,factor,integer,logical,numeric, andraw. -
required(logical value) - is input required (defaults toFALSE). IfTRUE, input must match the named element of an object provided indataargument (dataset inputs) or user has to provide an object of appropriateclass(standalone inputs). -
standalone(logical value) - does input depend on the object provided indata. Defaults toFALSE. -
length- provides set of rules for input'slengthrestriction. Defaults to (exactly: 1). It can accept various attributes, e.g.- if omitted or
NULL, it will default toexactly: 1 - if
integervalue is provided, it refers to exactlyNinputs:
- if omitted or
length: 10
is equivalent to (and will be stored internally as):
length:
exactly: 10
-
fromandtoattributes can be passed to define a range that input'slengthmust fall into:
length:
from: 1
to: 10
from or to can be omitted, and the sane defaults will be set implicitly. For instance, by omitting to, it will default to Inf, and if omitting from it will be set to 1.
length:
from: 1
is identical to:
length:
from: 1
to: Inf
or:
length:
to: 10
is equivalent to:
length:
from: 1
to: 10
-
value(a vector of an equivalentclass). Only available for standalone inputs, and must match theclassandlengthof a given input.NULLis also allowed, ifrequiredisFALSE. Additional checks are performed based on the inputclass. See Class-specific options for details.
An "ordinary" input with no class-specific options (see below) should look pretty much like this:
- name: l
label: Logical input
description: Nothing special about this, really. Just an ordinary logical input...
standalone: TRUE
value: TRUE
length: 1
required: FALSE
This will define a standalone logical input with TRUE as the default value, that will accept only one logical value and is not required.
-
regexp(character value) - a regular expression that all values in the input should match.regexpis omitted by default, and check will be performed only if attribute is non-NULL. -
nchar- sets restrictions on the number of characters. Accepts the same options aslengthattribute, only this time number of characters are checked.ncharis omitted from input definition by default. Checks are performed only if attribute is properly defined. -
matchable(logical value) - if set toTRUE, thevalueattribute is mandatory, and it (value) should accept a character vector that will be passed tomatch.argschoicesattribute, and user-provided value for the input is passed toarg. To demystify, ifcis a matchable character input:
- name: c
label: Character input
length:
min: 2
matchable: TRUE
value:
- un
- deux
- trois
- quatre
- cinq
and you're about to issue rapport("mytemplate", some_data, c = c("u", "d")), matchable will evaluate match.arg(c("u", "d"), c("un", "deux", "trois", "quatre", "cinq"), several.ok = TRUE). Note that several.ok is set to TRUE because length attribute requires at least 2 values to be matched. We will guess this one for you depending on the length attribute value. If the number of options exceeds the range [min, max], or differs from length$exactly, an error will be issued.
matchable attribute works on dataset inputs as well (unlike the non-matchable inputs). In that case, a named element is passed to arg argument in match.arg.
If user input is omitted, we'll grab the options from the value attribute to a vector and assign it to an input name in the rapport evaluation environment, according to the least limit set in length attribute. For instance, if user didn't map a value to an input, e.g. rapport("mytemplate", some_data), character vector c("un", "deux") will be assigned to symbol c. One could set length$min or length$exactly to 3, and c("un", "deux", "trois") will be assigned to c symbol instead, etc.
-
limit(a named list withminandmaxattributes) - checks if values ofnumeric/integerinputs fall into range defined byminandmax. Bothminandmaxshould be length-one vectors of appropriate class.limits are omitted by default. Checks are performed only iflimitattribute is provided.
-
nlevels(an integer or a named list) - defines number of levels given factor is allowed to have. See description forlengthorncharfor details. Attribute is omitted by default and checks will be performed only if non-NULL. -
matchable(a logical value) - seecharacterfor details. The only difference is that in case of factors, factor levels are matched instead.