R 访问全局变量失败
我试图在R中实现简单的身份验证,它将在版本控制下的源代码之外存储凭据。我知道使用R 访问全局变量失败,r,authentication,makefile,environment-variables,global,R,Authentication,Makefile,Environment Variables,Global,我试图在R中实现简单的身份验证,它将在版本控制下的源代码之外存储凭据。我知道使用options()和getOption()的方法,但使用它会迫使我从修订控制中删除项目级.Rprofile。我更喜欢使用另一种方法,即通过R关联Linux用户(ruser)的.bashrc导出凭据的环境变量,然后在特定于项目的.Rprofile中将这些凭据读入如下全局变量: CB_API_KEY <<- Sys.getenv("CB_API_KEY") 顶层Makefile: # Execute glo
options()
和getOption()
的方法,但使用它会迫使我从修订控制中删除项目级.Rprofile
。我更喜欢使用另一种方法,即通过R关联Linux用户(ruser
)的.bashrc
导出凭据的环境变量,然后在特定于项目的.Rprofile
中将这些凭据读入如下全局变量:
CB_API_KEY <<- Sys.getenv("CB_API_KEY")
顶层Makefile
:
# 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")
# 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
# 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
子项目级Makefile
:
# 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")
# 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
# 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
谢谢大家! 如果我理解正确,您有一个名为
Makefile
的shell脚本,它在批处理模式下调用R(R CMD batch
)来生成.Rprofile
文件,然后通过Rscript
运行另一个R会话,在该脚本中找不到您在.Rprofile
文件中定义的变量
您注意到全局变量不会在会话之间持久化,这是正确的
但是,除非您使用--no init file
或--vanilla
参数调用Rscript
,否则启动时应获取.Rprofile
文件
将
消息
添加到您的.r配置文件中
将让您知道它是否被调用以及何时被调用。好的,看起来我找到了解决此问题的方法。我在项目的子目录(import
)中创建了另一个.Rprofile
,其中处理需要身份验证,并将检索环境变量值到R全局变量的代码移到那里。我对它进行了测试,没有看到前面的错误消息(敲门!)。另一个好处是,现在代码更多地被划分为功能区域,因此更干净
吸取的教训(以及所有这些麻烦的原因):
AnyR session sources
.Rprofile
文件位于运行它的Any[current]目录中(我错误地假设R session sources.Rprofile
文件在初始运行时只运行一次,后续的R sessions不能这样做).请给我们看一下Makefile
和.Rprofile
的内容。特别是,我们需要查看对Rscript
的调用,以查看传递给它的命令参数。@RichieCotton:感谢您的评论和回答!根据你的要求,我用询问的细节更新了我的问题。很抱歉延迟-我脱机了。在.Rprofile
中包含源文件(“~/.Rprofile”)
很奇怪。这种疯狂的递归可能会导致问题。尝试将消息(“Inside.Rprofile”)
添加到.Rprofile
文件中,看看它是否被调用。@RichieCotton:1)将该语句放在中。Rprofile
实际上是我在一本著名出版商出版的R书中读到的一条建议。根据作者的说法,这个建议源于这样一个事实(?)R,如果寻找一个项目级.Rprofile
文件,不会自动寻找主文件。因此,建议并没有周期性依赖的风险(?);1')实际上,我的main.Rprofile
当前是空的,我只是将其作为将来可能的更改的源文件;2) 添加了消息
呼叫:正如预期的那样,我收到了消息。但最重要和神奇的是,我再也看不到错误消息了!再次感谢你的回答!我根据你的要求更新了我的问题。但是,正如您所看到的,我调用的是Rscript
,没有——没有init文件
和——vanilla
参数。因此,问题的原因可能是它是项目子目录中的.Rprofile
。另一个可能的原因可能是我如何通过Makefile
文件启动R会话。期待您的来信!对不起,我想,现在庆祝还为时过早。。。我刚刚找到了错误消息消失的原因:当从选项
方法返回时,我注释了.Rprofile
中的设置选项,但意外地忘记了返回到访问基于环境的全局变量。我不确定这些选项存储在哪里(我猜应该是.RData
),但它们似乎在R会话重新启动时保持不变。所以,你和我都正确地认为全局变量不能在会话间神奇地持久存在。