How to Get Parameters from Config File in R Script

How to get parameters from config file in R script

I'd go for YAML. Designed for human read-writability unlike XML. R package "yaml" exists on CRAN, I'm sure perl and java packages exist too.

http://ftp.heanet.ie/mirrors/cran.r-project.org/web/packages/yaml/index.html

You can't get more cross-platform than this:

http://yaml.org/

at least until I write a YAML FORTRAN package...

[edit]

Example. Suppose you have config.yml:

db:
host : foo.example.com
name : Foo Base
user : user453
pass : zoom

Then yaml.load_file("config.yml") returns:

$db
$db$pass
[1] "zoom"

$db$user
[1] "user453"

$db$name
[1] "Foo Base"

$db$host
[1] "foo.example.com"

So you do:

library(yaml)
config = yaml.load_file("config.yml")
dbConnect(PgSQL(), host=config$db$host, dbname=config$db$name, user=config$db$user, password=config$db$pass)

Add as many sections and parameters as you need. Sweeeeyit.

The yaml.load_file returns your configuration as an R list, and you can access named elements of lists using $-notation.

Reading and using a custom configuration file

Indeed, as Andrie suggested, using a .r config file is the easiest way to do it. I overlooked that option completely!

Thus, just make a .r file with the variables already in it:

#file:config.R
timestart <- 123456
timeend <- 654321
exclude <- c(409,255,265)
paid <- 1

In other script use:

source("config.R")

And voila. Thank you Andrie!

How can I read command line parameters from an R script?

Dirk's answer here is everything you need. Here's a minimal reproducible example.

I made two files: exmpl.bat and exmpl.R.

  • exmpl.bat:

    set R_Script="C:\Program Files\R-3.0.2\bin\RScript.exe"
    %R_Script% exmpl.R 2010-01-28 example 100 > exmpl.batch 2>&1

    Alternatively, using Rterm.exe:

    set R_TERM="C:\Program Files\R-3.0.2\bin\i386\Rterm.exe"
    %R_TERM% --no-restore --no-save --args 2010-01-28 example 100 < exmpl.R > exmpl.batch 2>&1
  • exmpl.R:

    options(echo=TRUE) # if you want see commands in output file
    args <- commandArgs(trailingOnly = TRUE)
    print(args)
    # trailingOnly=TRUE means that only your arguments are returned, check:
    # print(commandArgs(trailingOnly=FALSE))

    start_date <- as.Date(args[1])
    name <- args[2]
    n <- as.integer(args[3])
    rm(args)

    # Some computations:
    x <- rnorm(n)
    png(paste(name,".png",sep=""))
    plot(start_date+(1L:n), x)
    dev.off()

    summary(x)

Save both files in the same directory and start exmpl.bat. In the result you'll get:

  • example.png with some plot
  • exmpl.batch with all that was done

You could also add an environment variable %R_Script%:

"C:\Program Files\R-3.0.2\bin\RScript.exe"

and use it in your batch scripts as %R_Script% <filename.r> <arguments>

Differences between RScript and Rterm:

  • Rscript has simpler syntax
  • Rscript automatically chooses architecture on x64 (see R Installation and Administration, 2.6 Sub-architectures for details)
  • Rscript needs options(echo=TRUE) in the .R file if you want to write the commands to the output file

Config file in a csv (or txt) format

First thing I would suggest is looking into the config package.
It allows you to specify variables in a yaml text file. I haven't used it but it seems pretty neat and looks like it may be a good solution.

If you don't want to use that, then if your csv is something like this, with var names in one column and values in the next:

min_birthday_year,1920
max_birthday,Sys.Date() %m+% months(9)
min_startdate_year,2010
max_startdate_year,2022

then you could do something like this:

# Read in the file
# assuming that names are in one column and values in another
# will create vars using vals from second col with names from first

config <- read.table("config.csv", sep = ",")

# mapply with assign, with var names in one vector and values in the other
# eval(parse()) call to evaluate value as an expression - needed to evaluate the Sys.Date() thing.
# tryCatch in case you add a string value to the csv at some point, which will throw an error in the `eval` call

mapply(
function(x, y) {
z <- tryCatch(
eval(parse(text = y)),
error = function(e) y
)
assign(x, z, inherits = TRUE)
},
config[[1]],
config[[2]]
)

Can I import variables into R from a global file?

If it is ok to replace the parentheses with brace brackets then readRenviron will read in such files and perform the substitutions returning the contents as environmental variables.

# write out test file globals2.mk which uses brace brackets
Lines <- "num = 100
path = ./here/is/a/path
file = ${path}/file.csv"
cat(Lines, file = "globals2.mk")

readRenviron("globals2.mk")
Sys.getenv("num")
## [1] "100"
Sys.getenv("path")
## [1] "./here/is/a/path"
Sys.getenv("file")
## [1] "./here/is/a/path/file.csv"

If it is important to use parentheses rather than brace brackets, read in globals.mk, replace the parentheses with brace brackets and then write the file out again.

# write out test file - this one uses parentheses as in question
Lines <- "num = 100
path = ./here/is/a/path
file = $(path)/file.csv"
cat(Lines, file = "globals.mk")

# read globals.mk, perform () to {} substitutions, write out and then re-read
tmp <- tempfile()
L <- readLines("globals.mk")
cat(paste(chartr("()", "{}", L), collapse = "\n"), file = tmp)
readRenviron(tmp)

Is it possible to specify command line parameters to R-script in RStudio?

I know this question is old and the link below is old, but it answers the question. No, it's not possible (or wasn't as of Jan 29, 2012) to access command line arguments from RStudio.

Link
https://support.rstudio.com/hc/communities/public/questions/200659066-Accessing-command-line-options-in-RStudio?locale=en-us

How to parse INI like configuration files with R?

Here is an answer that was given to exact the same question on r-help in 2007 (thanks to @Spacedman for pointing this out):

Parse.INI <- function(INI.filename) 
{
connection <- file(INI.filename)
Lines <- readLines(connection)
close(connection)

Lines <- chartr("[]", "==", Lines) # change section headers

connection <- textConnection(Lines)
d <- read.table(connection, as.is = TRUE, sep = "=", fill = TRUE)
close(connection)

L <- d$V1 == "" # location of section breaks
d <- subset(transform(d, V3 = V2[which(L)[cumsum(L)]])[1:3],
V1 != "")

ToParse <- paste("INI.list$", d$V3, "$", d$V1, " <- '",
d$V2, "'", sep="")

INI.list <- list()
eval(parse(text=ToParse))

return(INI.list)
}

Actually, I wrote a short and presumably buggy function (i.e. not covering all corner cases) which works for me now:

read.ini <- function(x) {
if(length(x)==1 && !any(grepl("\\n", x))) lines <- readLines(x) else lines <- x
lines <- strsplit(lines, "\n", fixed=TRUE)[[1]]
lines <- lines[!grepl("^;", lines) & nchar(lines) >= 2] # strip comments & blank lines
lines <- gsub("\\r$", "", lines)
idx <- which(grepl("^\\[.+\\]$", lines))
if(idx[[1]] != 1) stop("invalid INI file. Must start with a section.")

res <- list()
fun <- function(from, to) {
tups <- strsplit(lines[(from+1):(to-1)], "[ ]*=[ ]*")
for (i in 1:length(tups))
if(length(tups[[i]])>2) tups[[i]] <- c(tups[[i]][[1]], gsub("\\=", "=", paste(tail(tups[[i]],-1), collapse="=")))
tups <- unlist(tups)
keys <- strcap(tups[seq(from=1, by=2, length.out=length(tups)/2)])
vals <- tups[seq(from=2, by=2, length.out=length(tups)/2)]
sec <- strcap(substring(lines[[from]], 2, nchar(lines[[from]])-1))
res[[sec]] <<- setNames(vals, keys)
}
mapply(fun, idx, c(tail(idx, -1), length(lines)+1))
return(res)
}

where strcap is a helper function that capitalizes a string:

strcap <- function(s) paste(toupper(substr(s,1,1)), tolower(substring(s,2)), sep="")

There are also some C solutions for this, like inih or libini that might be useful. I did not try them out, though.



Related Topics



Leave a reply



Submit