r之以 JavaScript 样式创建 R 列表作为配置对象

zhwl 阅读:41 2025-02-15 21:57:57 评论:0

我需要一个配置对象来保留我的 R 代码中使用的一些常量。这些是远程文件的 url、保存下载文件的目录、下载后要使用的本地文件名等。 我是 R 新手,这就是为什么我决定使用类似 JavaScript 的配置对象(特别是列表),类似于这样:

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 
}; 

请注意,可以使用“this”来引用当前对象并在其中进行一些计算/赋值。

我在R中到达的最远的地方是:

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

但是如果仍然需要计算 abs_data_dir 和其他类似值怎么办?在“构建”配置列表对象时是否可以完成这项工作?是否可以根据刚刚创建的列表成员派生新的命名列表成员,例如在 dplyr 包中使用 mutate() ?如果是这样,在 R 中是否有任何类似于 JS 的“this”来引用当前对象?

请您参考如下方法:

解决方案一

想到了

within,我在玩了一会儿之后想到了这个:

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" 

你可以把它变成一个函数:

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

按如下方式调用 list.eval({a = 1; b = a})


方案二

这是另一个函数,其用法更接近 list 的用法。它还会像 list 那样处理命名和未命名的参数:

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 


标签:JavaScript
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号