访问全局变量失败

时间:2014-02-24 11:04:10

标签: r authentication makefile environment-variables global

我试图在R中实现简单的身份验证,它将在修订控制下的源代码之外存储凭据。我知道使用options()getOption()的方法,但使用它会迫使我从版本控制中删除项目级.Rprofile。我更喜欢使用另一种方法,基于通过R关联的Linux用户.bashrc导出凭证的环境变量(ruser),然后将项目特定的.Rprofile中的这些凭证读入全局像这样的变量:

CB_API_KEY <<- Sys.getenv("CB_API_KEY")

但是,在R模块中访问此类全局变量失败,并且未找到消息“object'CB_API_KEY'”。我怀疑原因是我通过.Rprofile中的单独调用R CMD BATCH来源Makefile。执行R模块,我尝试访问这些全局变量,再次通过单独调用Makefile通过Rscript完成。因此,在我看来第一个R会话全局环境丢失,因此访问失败。我很感激您对此问题的意见和建议。

更新:以下是项目特定.Rprofile的内容以及项目的顶级和子项目级Makefile文件。相应地。

.Rprofile

# Execute global R profile first...
source("~/.Rprofile")

# ...then local project R setup

# Retrieve SRDA (SourceForge) credentials
SRDA_USER <<- Sys.getenv("SRDA_USER")
SRDA_PASS <<- Sys.getenv("SRDA_PASS")

# Retrieve CrunchBase API key
CB_API_KEY <<- Sys.getenv("CB_API_KEY")

# Another approach is to use options() and getOption(),
# but it requires removing this file from source control
options(SRDA_USER = "XXX", SRDA_PASS = "YYY", CB_API_KEY = "ZZZ")

顶级Makefile

# Major variable definitions

PROJECT="diss-floss"
HOME_DIR="~/diss-floss"
REPORT={$(PROJECT)-slides}

COLLECTION_DIR=import
PREPARATION_DIR=prepare
ANALYSIS_DIR=analysis
RESULTS_DIR=results
PRESENTATION_DIR=present

RSCRIPT=Rscript


# Targets and rules

all: rprofile collection preparation analysis results presentation

rprofile:
        R CMD BATCH ./.Rprofile

collection:
        cd $(COLLECTION_DIR) && $(MAKE)

preparation: collection
        cd $(PREPARATION_DIR) && $(MAKE)

analysis: preparation
        cd $(ANALYSIS_DIR) && $(MAKE)

results: analysis
        cd $(RESULTS_DIR) && $(MAKE)

presentation: results
        cd $(PRESENTATION_DIR) && $(MAKE)


## Phony targets and rules (for commands that do not produce files)

#.html
.PHONY: demo clean

# run demo presentation slides
demo: presentation
        # knitr(Markdown) => HTML page
        # HTML5 presentation via RStudio/RPubs or Slidify
        # OR
        # Shiny app

# remove intermediate files
clean:
        rm -f tmp*.bz2 *.Rdata

子项目级Makefile

# Major variable definitions

RSCRIPT=Rscript
#RSCRIPT=R CMD BATCH
R_OPTS=--no-save --no-restore --verbose
#R_OUT=> outputFile.Rout 2>&1

# --no-save --no-restore --verbose myRfile.R > outputFile.Rout 2>&1


# Targets and rules

collection: importFLOSSmole \
            importSourceForge \
            importAngelList \
            importCrunchBase

importFLOSSmole: getFLOSSmoleDataXML.R
        $(RSCRIPT) $(R_OPTS) $<

importSourceForge: getSourceForgeData.R
        $(RSCRIPT) $(R_OPTS) $<

importAngelList: getAngelListData.R
        $(RSCRIPT) $(R_OPTS) $<

importCrunchBase: getCrunchBaseDataAPI.R
        $(RSCRIPT) $(R_OPTS) $<

.PHONY: clean

# remove intermediate files
clean:
        rm -f tmp*.bz2 *.Rdata .Rout

目录结构很典型:

+ `ruser` home directory
|____+ project's home directory
     |____ `import` sub-directory
     |____ project's other sub-directories

谢谢!

2 个答案:

答案 0 :(得分:1)

如果我理解正确,你有一个名为Makefile的shell脚本,它以批处理模式(R CMD BATCH)调用R来获取.Rprofile文件,然后运行另一个R会话通过Rscript,找不到您在.Rprofile文件中定义的变量。

您注意到会话之间不会保留全局变量是正确的。

但是,除非您使用Rscript--no-init-file参数调用--vanilla,否则应在启动时获取.Rprofile文件。

messages添加到.Rprofile会告诉您是否以及何时调用它。

答案 1 :(得分:0)

好的,看起来我想出了如何解决这个问题。我在项目的子目录(.Rprofile)中创建了另一个import,其中处理需要身份验证,并将代码检索环境变量的值转移到R全局变量中。我测试了它,并没有看到以前的错误消息(敲木头!)。 其他好处现在代码更加分离为功能区域,因此更清洁

经验教训(以及所有这些问题的原因):

任何 R会话源.Rprofile文件在任何 [当前]目录中运行(我错误地认为R会话源.Rprofile文件只有一次,在初始运行时,后续R会话不能这样做。)