2

假设我有一个文件foo.R和一个正则表达式列表rex.txt。如果我把

rex <- paste(read.table("rex.txt", stringsAsFactors=FALSE)[[1]],collapse="|")

,然后当我使用加载时foo.R变量被正确初始化。当我编译并加载后者时也会发生同样的情况,这很好。rexfoo.Rlibrary()foo.Rfoo.Rc

然而,我想要的是变量的文字值rex包含在foo.Rc(当我调用时cmpfile),即,当foo.Rc加载时,变量rex从编译时的任何内容初始化rex.txt,类似于 Emacs Lisp eval-when-compile(这样我不必须复制rex.txt到我实际运行的服务器foo.Rc)。

可能吗?

4

2 回答 2

2

可以foo.R 在编译前修改,如下图。

测试数据:

text <- '
doSomething()
rex <- paste(read.table("rex.txt", stringsAsFactors=FALSE)[[1]],collapse="|")
doOtherStuff()
'

writeLines(text,"foo.R")

代码:

foo <- readLines("foo.R")

pattern <- "^rex\\s*<-.*$"

eval(parse(text=grep(pattern, foo, value=TRUE))[[1]])

newtext <- gsub(pattern, paste("rex <-",deparse(rex)), foo)

writeLines(newtext,"foo.R")

请注意,eval()rex <- ...在全局环境中执行创建此对象的行,以便deparse()可以找到它。我还假设您只有一行与pattern使用的匹配。

于 2013-09-04T21:42:24.737 回答
1

我的解决方案类似于 Ferdinand.kraft 的解决方案,但我建议使用 parse/substitute 而不是正则表达式。如果您需要对文件中的多个变量执行此操作,这应该更灵活一些。

substitutedFile <- "foo-sub.R"

#save rex into an environment
a <- new.env()    
local(envir=a, {
  rex <- paste(read.table("rex.txt", stringsAsFactors=FALSE)[[1]],collapse="|")    
})

#Substitute variables from a into foo.R and write it back out
lines <- lapply(parse("foo.R"), function(expr) {
  deparse(eval(substitute(substitute(expr, a), list(expr=expr)))) 
})    
writeLines(paste(lines, collapse="\n"),substitutedFile)

cmpfile(substitutedFile)
于 2013-09-04T22:10:25.547 回答