为什么项目在从Makefile运行时无法访问renv()函数?

huangapple go评论65阅读模式
英文:

Why does the project not access renv() when running from a Makefile?

问题

我在项目的renv和系统中安装了不同版本的tidyverse。当我使用Makefile执行项目时,由于某种原因它不使用renv中的版本,而是使用系统范围的版本。当我直接在R文件中执行代码时,它使用renv中的版本。

这可能与初始化位置有关吗?renv是在项目根文件夹中初始化的,但Makefile位于代码文件夹中,比根文件夹下一级。

非常感谢任何建议!

谢谢,
Doron

编辑:抱歉,由于问题的性质,我不清楚哪些信息会有用。

我的Makefile如下所示:

imp := import/
fn := functions/
mw := merge_wealthSupplement/
cm := clean_merged/
ccl := clean_clans/
mc := merge_clans/
cv := clean_variables/
dsc := descriptives/
an := analysis/
o := output/
i := input/
s := src/


targets := $(dsc)output/%.pdf
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
R = R --vanilla --args "" < "$<" "$(mkfile_path)" 	# $< marks the first prerequisite

all: $(targets)

# Import data from PSID needs username and password so can't run automatically
# $(imp)$(o)data.Rds: $(imp)$(s)import.R
# 	R --vanilla --args "" < "import/src/import.R"

$(mw)$(o)merged.Rds: $(mw)$(s)merge_wealthSupplement.R $(imp)$(o)data.Rds
	$(R)

$(cm)$(o)clean_merged.Rds: $(cm)$(s)clean_merged.R $(mw)$(o)merged.Rds $(fn)$(s)functions.R
	$(R)

$(ccl)$(o)sample.Rds: $(ccl)$(s)clean_clans.R $(cm)$(o)clean_merged.Rds $(fn)$(s)functions.R \
$(ccl)$(s)functions.R
	$(R)	

$(mc)$(o)merged_clans.Rds: $(mc)$(s)merge_clans.R $(ccl)$(o)sample.Rds \
$(cm)$(o)clean_merged.Rds $(fn)$(s)functions.R
	$(R)

$(cv)$(o)clean_variables.Rds: $(cv)$(s)clean_variables.R $(mc)$(o)merged_clans.Rds
	$(R)

$(targets): $(dsc)$(s)descriptives.R $(cv)$(o)clean_variables.Rds $(an)$(s)analysis.R
	$(R)	


.PHONY: clean

clean: 
	rm $(objects)

它保存在.../project_name/code/Makefile中。

我注意到问题的R脚本是第四个makefile执行命令:clean_clans.R

clean_clans.R的开头如下所示:

if (!require("pacman")) install.packages(
  "pacman", repos = "http://cran.us.r-project.org")
pacman::p_load(tidyverse)

它保存在.../project_name/code/clean_clans/src/clean_clans.R中。

renv的锁定文件位于.../project_name/renv.lock中。

当我直接从文件中执行clean_clans.R时,没有问题。当我通过终端执行它时,在到达pick()时出现错误,这是在较新的dplyr版本中引入的。

当我打印出sessionInfo时,我发现当我直接从文件中执行代码时,所有软件包版本与renv的锁定文件一致,但当我从Makefile中执行时,与系统(而不是锁定文件)一致。

非常感谢您的所有帮助,我很乐意提供任何进一步的信息!
Doron

英文:

I have different versions of tidyverse installed in a project renv and on my system. When I execute my project using a Makefile, it doesn't use the renv versions for some reason, instead using the system-wide versions. When I execute the code in the R file directly it uses the renv versions.

Could this have something to do with the initialization locations? renv was initialized in the project root folder but the Makefile is in the code folder, one level down.

Would appreciate any advice!

Thanks,
Doron

EDIT: apologies, was unclear to me what information would be useful due to the nature of the issue.

My Makefile looks like this:

imp := import/
fn := functions/
mw := merge_wealthSupplement/
cm := clean_merged/
ccl := clean_clans/
mc := merge_clans/
cv := clean_variables/
dsc := descriptives/
an := analysis/
o := output/
i := input/
s := src/


targets := $(dsc)output/%.pdf
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
R = R --vanilla --args "" < "$<" "$(mkfile_path)" 	# $< marks the first prerequisite

all: $(targets)

# Import data from PSID needs username and password so can't run automatically
# $(imp)$(o)data.Rds: $(imp)$(s)import.R
# 	R --vanilla --args "" < "import/src/import.R"

$(mw)$(o)merged.Rds: $(mw)$(s)merge_wealthSupplement.R $(imp)$(o)data.Rds
	$(R)

$(cm)$(o)clean_merged.Rds: $(cm)$(s)clean_merged.R $(mw)$(o)merged.Rds $(fn)$(s)functions.R
	$(R)

$(ccl)$(o)sample.Rds: $(ccl)$(s)clean_clans.R $(cm)$(o)clean_merged.Rds $(fn)$(s)functions.R \
$(ccl)$(s)functions.R
	$(R)	

$(mc)$(o)merged_clans.Rds: $(mc)$(s)merge_clans.R $(ccl)$(o)sample.Rds \
$(cm)$(o)clean_merged.Rds $(fn)$(s)functions.R
	$(R)

$(cv)$(o)clean_variables.Rds: $(cv)$(s)clean_variables.R $(mc)$(o)merged_clans.Rds
	$(R)

$(targets): $(dsc)$(s)descriptives.R $(cv)$(o)clean_variables.Rds $(an)$(s)analysis.R
	$(R)	


.PHONY: clean

clean: 
	rm $(objects)

It is saved in .../project_name/code/Makefile

The R script where I notice the problem is the fourth makefile execution command: clean_clans.R

clean_clans.R starts like this:

if (!require("pacman")) install.packages(
  "pacman", repos = "http://cran.us.r-project.org")
pacman::p_load(tidyverse)

It is saved in .../project_name/code/clean_clans/src/clean_clans.R

The renv lockfile is in .../project_name/renv.lock

When I execute clean_clans.R from the file itself there is no problem. When I execute it via Terminal it errors upon getting to pick(), which was introduced in a newer dplyr version.

When I print out sessionInfo I see that all the package versions are consistent with the renv lockfile when I execute the code directly from the file, but are consistent with the system (not the lockfile) when I execute from the Makefile.

Thanks so much for all the help and I would be happy to supply any further info!
Doron

答案1

得分: 1

renv项目通常通过项目文件夹中的.Rprofile来激活,该文件依赖于R的工作目录与包含.Rprofile的目录相匹配。因此,在启动R之前,您很可能需要确保将工作目录设置为项目的根目录。

编辑:查看您的Makefile,我认为问题出在这里:

> R = R --vanilla --args "" < "$<" "$(mkfile_path)" # $< marks the first prerequisite

在这种情况下,您确实希望加载项目的.Rprofile(因为这是renv在启动时激活自身的方式),因此您应该删除--vanilla的使用。

英文:

renv projects are normally activated via a .Rprofile contained in the project folder, which relies on R's working directory matching the directory containing that .Rprofile. To wit, you most likely need to ensure that you set the working directory to the project root directory before launching R.

EDIT: Looking at your Makefile, I think the culprit is this:

> R = R --vanilla --args "" < "$<" "$(mkfile_path)" # $< marks the first prerequisite

In this case, you do want the project's .Rprofile to be sourced (since that's how renv activates itself on startup), so you should remove the --vanilla usage.

huangapple
  • 本文由 发表于 2023年8月8日 23:50:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76861215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定