How to get parameters from config file in R script

What you describe here is a desire for common configuration across systems, platforms, languages, ...

That is a big topic and much ink has been spilled on this. Some people see XML as the answer, other prefer simpler related formats like JSON. You could also try Apache-style config files as most languages have libraries for it (but R may be an exception).

I happen to like Google ProtocolBuffers which are fast, efficient, cross-platform, multi-language, forward-compatible ... but have the one downside of not being ascii files (though you can read ascii files first and then create proto files). For R, there is the RProtoBuf package.


You can source() an R script in at the top of your main script that reads in your config file parameters. Depending on who you are sharing your scripts with, there may be issues with database security and having the login information in an unencrypted format. There is a recent question here on SO about that, I'll see if I can find it in a minute.

Anyways, store all of your db parameters in a file named config.R and then on your main script, run:

source("config.R") #Will create four objects named "db_host, db_name, db_user, db_pass"

dbConnect(PgSQL(), host=db_host, dbname=db_name, user=db_user, password=db_pass)

The built-in R function read.table handles this INI format well if you suggest that it split columns using the equals sign.

key.val <- read.table(filename, sep="=", col.names=c("key","value"), as.is=c(1,2))

If you want a more traditional INI behavior, so that you can use multiple config files, try assigning the key-value pairs to an R environment. For example:

read.config <- function(filename) {
  conf.vars <- new.env()
  for (f in filename) {
    if (file.exists(f)) {
      header <- 1
      key.val <- read.table(f, sep="=", col.names=c("key","value"), skip=header,
          as.is=c(1,2))
      for (kidx in seq(length(key.val$key))) {
        assign(key.val[["key"]][kidx], key.val[["value"]][kidx], envir=conf.vars)
      }
    }
  }
  return(conf.vars)
}

get.config <- function(name) {
  kv.env=read.config(c("project.cfg","project_local.cfg"))
  return(kv.env[[name]])
}

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.

Tags:

Unix

R