Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating R list as config object in JavaScript style

I need a config object to keep some constants being used in my R code. These are url for remote file, directory for keeping downloaded files, local filenames to be used after downloading, etc. I'm R newbie that is why I decided to use JavaScript-like config object (particularly list) similar to something like this:

var config = {
    wd           : "/some/working/dir",
    zipSrc       : "http://www.example.com/remote_data_file.zip",
    data_dir     : "data",
    data_zip     : "data.zip",
    data_txt     : "data.txt",
    abs_data_dir : this.wd + this.data_dir,
    abs_data_zip : this.abs_data_dir + this.data_zip,
    abs_data_txt : this.abs_data_dir + this.data_txt
};

Notice that one can use "this" to reference current object and made some calculation/assignments right inside it.

The most distant place I reached in R is:

config <- list(wd           = getwd(),
               zipSrc       = "http://www.example.com/remote_data_file.zip",
               data_dir     = "data",
               data_zip     = "data.zip",
               data_txt     = "data.txt")

But what if one still needs to calculate abs_data_dir and other similar values? Is it possible to do that job while "building" config list object? Is it possible to derive new named list members based on just created ones like using mutate() in dplyr package? If so is there in R any analogue to JS' "this" to reference current object?

like image 448
erop Avatar asked Jan 18 '26 03:01

erop


1 Answers

Solution 1

within comes to mind, I came to this after playing with it for a bit:

config = rev(within(list(), {
   wd           = "/some/working/dir"
   zipSrc       = "http://www.example.com/remote_data_file.zip"
   data_dir     = "data"
   data_zip     = "data.zip"
   data_txt     = "data.txt"
   abs_data_dir = file.path(wd, data_dir)
   abs_data_zip = file.path(abs_data_dir, data_zip)
   abs_data_txt = file.path(abs_data_dir, data_txt)
}))

config
# $wd
# [1] "/some/working/dir"

# $zipSrc
# [1] "http://www.example.com/remote_data_file.zip"

# $data_dir
# [1] "data"

# $data_zip
# [1] "data.zip"

# $data_txt
# [1] "data.txt"

# $abs_data_dir
# [1] "/some/working/dir/data"

# $abs_data_zip
# [1] "/some/working/dir/data/data.zip"

# $abs_data_txt
# [1] "/some/working/dir/data/data.txt"

You can turn this into a function:

list.eval <- function(...) rev(within(list(), ...))

to be called as follows list.eval({a = 1; b = a}).


Solution 2

Here is another function with a usage closer to list's. It will also handle both named and unnamed arguments like list does:

list.eval <- function(...) {
   e <- new.env()
   argl <- as.list(sys.call())[-1L]
   naml <- names(argl)
   .eval.assign <- function(expr, name) {
      value <- eval(expr, envir = e)
      if (name != "") assign(name, value, envir = e)
      return(value)
   }
   setNames(Map(.eval.assign, argl, naml), naml)
}

z <- 10
list.eval(a = 1, b = z, c = a, 10)
# $a
# [1] 1
# 
# $b
# [1] 10
# 
# $c
# [1] 1
# 
# [[4]]
# [1] 10
like image 123
flodel Avatar answered Jan 19 '26 19:01

flodel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!