r - 我可以将变量从全局文件导入 R 吗?
问题描述
我正在将一个 R 脚本集成到一个更大的项目中,该项目与一个 Makefile 一起生成一些图形。在这个较大的项目中,我有一个名为的文件globals.mk
,其中包含项目中许多其他脚本使用的全局变量。例如,我想运行的模拟次数是我想在这个 R 脚本中使用的一个全局变量。我可以将其“导入”为变量,还是需要手动定义 R 脚本中的每个变量?
编辑:这是我需要阅读的全局变量示例。
num = 100
path = ./here/is/a/path
file = $(path)/file.csv
我希望 R 脚本将变量设置num
为 100(或“100”)、path
“./here/is/a/path”和file
“./here/is/a/path/file.csv”。
解决方案
如果.mk
文件有除直接变量扩展以外的任何内容(例如更复杂make
的 -rules/tricks/functions),最好相信make
为您进行扩展,然后将其读入。我发现这里有一个帖子转储所有变量内容(处理后)。
TL;博士
expand_mkvars <- function(path, aslist = FALSE) {
stopifnot(file.exists(mk <- Sys.which("make")))
tf <- tempfile(fileext = ".mk")
# needed on my windows system
tf <- normalizePath(tf, winslash = "/", mustWork = FALSE) # tempfile should suffice
on.exit(suppressWarnings(file.remove(tf)), add = TRUE)
writeLines(c(".PHONY: printvars",
"printvars:",
"\t@$(foreach V,$(sort $(.VARIABLES)), \\",
"\t $(if $(filter-out environment% default automatic, \\",
"\t $(origin $V)),$(warning $V=$($V))))"), con = tf)
out <- system2(mk, c("-f", shQuote(path), "-f", shQuote(tf), "-n", "printvars"),
stdout = TRUE, stderr = TRUE)
out <- out[grepl(paste0("^", tf), out)]
out <- gsub(paste0("^", tf, ":[0-9]+:\\s*"), "", out)
known_noneed <- c(".DEFAULT_GOAL", "CURDIR", "GNUMAKEFLAGS", "MAKEFILE_LIST", "MAKEFLAGS")
out <- out[!grepl(paste0("^(", paste(known_noneed, collapse = "|"), ")="), out)]
if (aslist) {
spl <- strsplit(out, "=")
nms <- sapply(spl, `[[`, 1)
rest <- lapply(spl, function(a) paste(a[-1], collapse = "="))
setNames(rest, nms)
} else out
}
在行动:
expand_mkvars("~/StackOverflow/karthikt.mk")
# [1] "file=./here/is/a/path/file.csv" "num=100"
# [3] "path=./here/is/a/path"
expand_mkvars("~/StackOverflow/karthikt.mk", aslist = TRUE)
# $file
# [1] "./here/is/a/path/file.csv"
# $num
# [1] "100"
# $path
# [1] "./here/is/a/path"
我没有在其他系统上测试过,所以您可能需要调整known_noneed
以添加弹出的额外变量。根据您的需要,您可能能够更智能地进行过滤(例如,您的变量都没有以大写字母开头),但对于这个示例,我将其保留make
为提供给我们的已知不想要的变量。
该博客文章建议使用虚假目标
.PHONY: printvars
printvars:
@$(foreach V,$(sort $(.VARIABLES)), \
$(if $(filter-out environment% default automatic, \
$(origin $V)),$(warning $V=$($V))))
(有些是制表符,不是所有的空格,对于 非常重要make
)
不幸的是,它产生的输出超出了技术上的需要:
$ /c/Rtools/bin/make.exe -f ~/StackOverflow/karthikt.mk printvars
C:/Users/r2/StackOverflow/karthikt.mk:10: .DEFAULT_GOAL=all
C:/Users/r2/StackOverflow/karthikt.mk:10: CURDIR=/Users/r2/Projects/Ford/shiny/shinyobjects/inst
C:/Users/r2/StackOverflow/karthikt.mk:10: GNUMAKEFLAGS=
C:/Users/r2/StackOverflow/karthikt.mk:10: MAKEFILE_LIST= C:/Users/r2/StackOverflow/karthikt.mk
C:/Users/r2/StackOverflow/karthikt.mk:10: MAKEFLAGS=
C:/Users/r2/StackOverflow/karthikt.mk:10: SHELL=sh
C:/Users/r2/StackOverflow/karthikt.mk:10: file=./here/is/a/path/file.csv
C:/Users/r2/StackOverflow/karthikt.mk:10: num=100
C:/Users/r2/StackOverflow/karthikt.mk:10: path=./here/is/a/path
make: Nothing to be done for 'printvars'.
所以我们需要一点过滤,因此函数中的大部分代码。
编辑:它readRenviron
-to-envvar 对您来说是最好的方法,将此make
调用的输出重定向到另一个文件,解析相关行,然后readRenviron
在该新文件上执行并不难。由于使用了两个临时文件,这似乎更间接,但它们已被清理,因此无需担心。
推荐阅读
- excel - 仅在 ComboBox 中显示可见工作表
- python-3.x - 如何使用 apply 轻松更改 tf-idf 相似性数据框
- android - Android Studio XML Parse 错误:prolog 中不允许内容
- java - org.hibernate.hql.internal.ast.QuerySyntaxException:即使我使用实体的类名,也没有映射员工
- android - 无法覆盖片段中的 onConfigurationChange
- leaflet - LeafletJS中的笛卡尔坐标到LatLng
- flutter - 我想在单击 onTap 时更改作为 ListView 子项的 CustomListTile 的颜色,并将其他子项颜色设置为默认颜色?
- swift - RealityKit 和 Reality Composer – 图像识别
- reactjs - 类型错误:this.getISO 不是函数
- laravel - 如何在 vuejs + laravel 中检索复选框值