configr is an integrated parser package that json, ini, yaml and toml format files can now be processed. The vignette will walk you through the basics of using configr to extend existing parser in R.
Example of json, ini, yaml, toml can be used follow the instructions below.
library(configr)
config.json <- system.file('extdata', 'config.json', package='configr')
config.ini <- system.file('extdata', 'config.ini', package='configr')
config.yaml <- system.file('extdata', 'config.yaml', package='configr')
config.toml <- system.file('extdata', 'config.toml', package='configr')
is.json.file
, is.ini.file
, is.yaml.file
and is.toml.file
can be used to check the configuration file type. If input file were coincident with required, it will return TRUE. get.config.type
will using above functions and get the file type name: json, ini, yaml, toml or FALSE.
is.json.file(config.json)
#> [1] TRUE
is.toml.file(config.toml)
#> [1] TRUE
is.ini.file(config.ini)
#> [1] TRUE
is.yaml.file(config.yaml)
#> [1] TRUE
get.config.type(config.json)
#> [1] "json"
get.config.type(config.yaml)
#> [1] "yaml"
get.config.type(config.ini)
#> [1] "ini"
get.config.type(config.toml)
#> [1] "toml"
Section names of configuration file can be get using eval.config.sections
. Python package ConfigParser sections
inspired us to add this function.
eval.config.sections(config.ini)
#> [1] "default" "comments" "extra_list_parse"
#> [4] "other_config_parse" "rcmd_parse" "bash_parse"
#> [7] "mulitple_parse" "glue_parse"
eval.config.sections(config.toml)
#> [1] "bash_parse" "comments" "default"
#> [4] "extra_list_parse" "glue_parse" "mulitple_parse"
#> [7] "other_config_parse" "title"
read.config
can read a configuration file in R and as a list object that can pass parameter to inner read function (fromJSON/read.ini/yaml.load_file/parseToml) accordingly.
# Read in R as a list (JSON/INI/YAML/TOML be suported)
# fromJSON/read.ini/readLines/yaml.load parameters can be automatch by parameter name (encoding .etc.)
read.config(file = config.toml)
#> List of 8
#> $ bash_parse :List of 2
#> ..$ parsed: chr "bash"
#> ..$ raw : chr "#>#echo bash#<#"
#> $ comments :List of 1
#> ..$ version: chr "0.2.3"
#> $ default :List of 1
#> ..$ debug: chr "{{debug}} {{debug2}}"
#> $ extra_list_parse :List of 2
#> ..$ parsed: chr "1"
#> ..$ raw : chr "{{yes}}"
#> $ glue_parse :List of 4
#> ..$ parsed_1: chr [1:10] "1" "2" "3" "4" ...
#> ..$ parsed_2: int [1:10] 1 2 3 4 5 6 7 8 9 10
#> ..$ raw_1 : chr "!!glue {1:10}"
#> ..$ raw_2 : chr "!!glue_numeric {1:10}"
#> $ mulitple_parse :List of 2
#> ..$ parsed: chr "configr, configr, yes, 1, config, config, no, 0"
#> ..$ raw : chr "@>@str_replace('config','g$','gr')@<@, #>#echo configr#<#, {{key:yes_flag}}, {{yes}}, @>@str_replace('configr',"| __truncated__
#> $ other_config_parse:List of 2
#> ..$ parsed: chr "yes no"
#> ..$ raw : chr "{{key:yes_flag}} {{key:no_flag}}"
#> $ title : chr "TOML Example"
eval.config
return a value or a list object containing the file path, config group, filetype as the attribute.
# Get the same obj with config package, only get the
# 'default or R_CONFIG_ACTIVE config sets' in config.cfg or R_CONFIGFILE_ACTIVE
eval.config(file = config.yaml)
#> $debug
#> [1] "{{debug}} {{debug2}}"
#>
#> attr(,"config")
#> [1] "default"
#> attr(,"configtype")
#> [1] "yaml"
#> attr(,"file")
#> [1] "/tmp/RtmpLtnjZx/Rinst1311ce1cf4fc/configr/extdata/config.yaml"
# Read designated section
eval.config(file = config.json, config = "comments")
#> $version
#> [1] "0.2.3"
#>
#> attr(,"config")
#> [1] "comments"
#> attr(,"configtype")
#> [1] "json"
#> attr(,"file")
#> [1] "/tmp/RtmpLtnjZx/Rinst1311ce1cf4fc/configr/extdata/config.json"
# Read designated section with its one value
eval.config(file = config.ini, config = "comments", value = "version")
#> [1] "0.2.3"
eval.config.merge
will merge multiple sections (equal to config
in eval.config
function) and reduce the layer of configuration file.
eval.config.merge(file = config.json, sections = c('default', 'comments'))
#> $debug
#> [1] "{{debug}} {{debug2}}"
#>
#> $version
#> [1] "0.2.3"
#>
#> attr(,"config")
#> [1] "default" "comments"
#> attr(,"configtype")
#> [1] "json"
#> attr(,"file")
#> [1] "/tmp/RtmpLtnjZx/Rinst1311ce1cf4fc/configr/extdata/config.json"
eval.config.merge(file = config.toml, sections = c('default', 'comments'))
#> $debug
#> [1] "{{debug}} {{debug2}}"
#>
#> $version
#> [1] "0.2.3"
#>
#> attr(,"config")
#> [1] "default" "comments"
#> attr(,"configtype")
#> [1] "toml"
#> attr(,"file")
#> [1] "/tmp/RtmpLtnjZx/Rinst1311ce1cf4fc/configr/extdata/config.toml"
convert.config
will read a configuration file and write a configuration file with appointed file type (json. ini, yaml). Moreover, write.config
is similar to convert.config
but using the list object rather than a file.
# Convert YAML configuration file to JSON format
out.json <- tempfile(, fileext = ".json")
convert.config(file = config.yaml, out.file = out.json, convert.to = "JSON")
#> [1] TRUE
get.config.type(out.json)
#> [1] "json"
# Generate a JSON format configuration file
list.test <- list(a=c(123,456))
out.fn <- sprintf("%s/test.json", tempdir())
write.config(config.dat = list.test, file.path = out.fn, write.type = "json")
#> [1] TRUE
get.config.type(out.fn)
#> [1] "json"
# Generate a YAML format configuration file with defined indent
write.config(config.dat = list.test, file.path = out.fn, write.type = "yaml", indent = 4)
#> [1] TRUE
get.config.type(out.fn)
#> [1] "yaml"
configr own several userful extra parse function, you can use the parse.extra
to finish these work for any list object. Of course, read.config
, eval.config
and eval.config.merge
can directly using parse.extra
by passing parameters to parse.extra
.
extra.list
can be used to parse the value of {{debug}}
to self
if you setted extra.list = list(debug = 'self')
other.config
can be used to parse the value of {{key:yes_flag}}
to yes
if you setted other.config = system.file('extdata', 'config.other.yaml', package='configr')
which content can be founded below.rcmd.parse
can be used to parse the value of @>@str_replace('config','g$','gr')@<@
to configr
if you setted rcmd.parse = TRUE
.bash.parse
can be used to parse the value of #>#echo bash#<#
to bash
if you setted bash.parse = TRUE
.glue.parse
can be used to paste the value of !!glue {1:5}
to ["1", "2", "3", "4", "5"]
; !!glue_numeric {1:5}
to [1, 2, 3, 4, 5]Note: glue.parse
using the glue
package glue
function to do that. Just like glue(‘{1:5}’) and be processed by unname(unlist(x)). The !!glue
can be changed if you setted glue.flag
. It is a remarkable fact that only contain the glue.flag
character be parsed and the order of item will be changed if the glue
result were multiple values. e.g. ['{a}', '!!glue {1:5}', '{{a}}']
will be parsed to ['{a}', '1', '2', '3', '4', '5', '{{a}}']
other.config <- system.file('extdata', 'config.other.yaml', package='configr')
read.config(file = other.config)
#> $key
#> $key$test_parse
#> [1] 123
#>
#> $key$test_parse2
#> [1] 234
#>
#> $key$yes_flag
#> [1] "yes"
#>
#> $key$no_flag
#> [1] "no"
#>
#>
#> $`samtools@1.3.1`
#> $`samtools@1.3.1`$source_dir
#> [1] "/tmp"
config.1 <- read.config(file = config.json)
config.1$default
#> $debug
#> [1] "{{debug}} {{debug2}}"
read.config(file = config.json, extra.list = list(debug = "self", debug2 = "self2"))$default
#> $debug
#> [1] "self self2"
sections <- c('default', 'other_config_parse')
config.1[sections]
#> $default
#> $default$debug
#> [1] "{{debug}} {{debug2}}"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "{{key:yes_flag}} {{key:no_flag}}"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
read.config(file = config.json, extra.list = list(debug = "self", debug2 = "self2"),
other.config = other.config)[sections]
#> $default
#> $default$debug
#> [1] "self self2"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "yes no"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
sections <- c('default', 'other_config_parse', 'rcmd_parse')
# The followed two line command will return the same value
config.1[sections]
#> $default
#> $default$debug
#> [1] "{{debug}} {{debug2}}"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "{{key:yes_flag}} {{key:no_flag}}"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
#>
#>
#> $rcmd_parse
#> $rcmd_parse$raw
#> [1] "@>@ Sys.Date() @<@"
read.config(file = config.json, extra.list = list(debug = "self", debug2 = "self2"),
other.config = other.config, rcmd.parse = T)[sections]
#> $default
#> $default$debug
#> [1] "self self2"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "yes no"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
#>
#>
#> $rcmd_parse
#> $rcmd_parse$raw
#> [1] "2017-06-22"
parse.extra(config.1, extra.list = list(debug = "self", debug2 = "self2"),
other.config = other.config, rcmd.parse = T)[sections]
#> $default
#> $default$debug
#> [1] "self self2"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "yes no"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
#>
#>
#> $rcmd_parse
#> $rcmd_parse$raw
#> [1] "2017-06-22"
sections <- c('default', 'other_config_parse', 'rcmd_parse', 'mulitple_parse')
config.1[sections]
#> $default
#> $default$debug
#> [1] "{{debug}} {{debug2}}"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "{{key:yes_flag}} {{key:no_flag}}"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
#>
#>
#> $rcmd_parse
#> $rcmd_parse$raw
#> [1] "@>@ Sys.Date() @<@"
#>
#>
#> $mulitple_parse
#> $mulitple_parse$raw
#> [1] "@>@str_replace('config','g$','gr')@<@, #>#echo configr#<#, {{key:yes_flag}}, {{yes}}, @>@str_replace('configr','r','')@<@, #># echo config#<#, {{key:no_flag}}, {{no}}"
#>
#> $mulitple_parse$parsed
#> [1] "configr, configr, yes, 1, config, config, no, 0"
parse.extra(config.1, extra.list = list(debug = "self", debug2 = "self2", yes = "1", no = "0"),
other.config = other.config, rcmd.parse = T, bash.parse = T)[sections]
#> $default
#> $default$debug
#> [1] "self self2"
#>
#>
#> $other_config_parse
#> $other_config_parse$raw
#> [1] "yes no"
#>
#> $other_config_parse$parsed
#> [1] "yes no"
#>
#>
#> $rcmd_parse
#> $rcmd_parse$raw
#> [1] "2017-06-22"
#>
#>
#> $mulitple_parse
#> $mulitple_parse$raw
#> [1] "configr, configr, yes, 1, config, config, no, 0"
#>
#> $mulitple_parse$parsed
#> [1] "configr, configr, yes, 1, config, config, no, 0"
# glue parse
raw <- c("a", "!!glue{1:5}", "c")
list.raw <- list(glue = raw, nochange = 1:10)
list.raw
#> $glue
#> [1] "a" "!!glue{1:5}" "c"
#>
#> $nochange
#> [1] 1 2 3 4 5 6 7 8 9 10
expect.parsed.1 <- c("a", "1", "2", "3", "4", "5", "c")
expect.parsed.2 <- list(glue = expect.parsed.1, nochange = 1:10)
parse.extra(list.raw, glue.parse = TRUE, glue.flag = "!!glue")
#> $glue
#> [1] "a" "1" "2" "3" "4" "5" "c"
#>
#> $nochange
#> [1] 1 2 3 4 5 6 7 8 9 10