Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Absolute ggplot graph file path generated using rmarkdown::render() #2365

Closed
4 of 5 tasks
erikaduan opened this issue May 30, 2022 · 5 comments
Closed
4 of 5 tasks

Absolute ggplot graph file path generated using rmarkdown::render() #2365

erikaduan opened this issue May 30, 2022 · 5 comments
Labels
duplicate already another issue about this theme: paths path related improvment / issue

Comments

@erikaduan
Copy link

erikaduan commented May 30, 2022

Checklist

When filing a bug report, please check the boxes below to confirm that you have provided us with the information we need. Have you:

  • formatted your issue so it is easier for us to read?

  • included a minimal, self-contained, and reproducible example?

  • pasted the output from xfun::session_info('rmarkdown') in your issue?

  • upgraded all your packages to their latest versions (including your versions of R, the RStudio IDE, and relevant R packages)?

  • installed and tested your bug with the development version of the rmarkdown package using remotes::install_github("rstudio/rmarkdown")?

Issue details

I am trying to create a tutorial on how to automate R report generation and have created a contained project at https://github.com/erikaduan/abs_labour_force_report.

I have created an R markdown report template here, which outputs a ggplot graph. When I render this report template directly, the github document contains the correct relative figure path to display my ggplot graph.

![](02_create_report_template_files/figure-gfm/unnamed-chunk-2-1.png)<!-- -->

I then attempt to render this template using a list of YAML parameters with another script here.

# Create data frame of the dot product of all parameter values 
params_df <- expand.grid(unique(labour_force$sex), unique(labour_force$measure),
                         stringsAsFactors = FALSE)  

# Input template report and parameters to output all html reports
for (i in 1:nrow(params_df)) {
  rmarkdown::render(
    input = here("code",
                 "02_create_report_template.Rmd"),
    output_format = github_document(), 
    params = list(sex = params_df[i, 1],
                  measure = params_df[i, 2]),
    output_dir = here("output"), 
    output_file = here("output",
                       glue::glue("{params_df[i, 1]}_{params_df[i, 2]}_report.md"))
  )
}

It generates the set of reports by parameters of interest, but the output path for my ggplot graph seems to no longer be relative in the rendered github document (an example here).

![](/home/runner/work/abs_labour_force_report/abs_labour_force_report/output/female_full-time_report_files/figure-gfm/unnamed-chunk-2-1.png)<!-- -->

The problem seems to be the generation of /home/runner/work/abs_labour_force_report/abs_labour_force_report/, which is a new observation for me.

I am trying to minimise the number of packages to load, by not using tidyverse and using individual packages and my renv lockfile is here. I'm wondering if this has contributed to this problem, but it doesn't make sense that the original report template can successfully render.

A second minor observation is that html documents are also rendered in my output directory despite adding the code below to my report template.

  github_document:
    html_preview: false

Many thanks in advance!

Update: The absolute file path first generated is my local file path i.e. ![](C:/Users/Erika/OneDrive/Desktop/git_repos/abs_labour_force_report/output/all_full-time_report_files/figure-gfm/unnamed-chunk-2-1.png), which then gets overwritten into ![](/home/runner/work/abs_labour_force_report/abs_labour_force_report/output/female_full-time_report_files/figure-gfm/unnamed-chunk-2-1.png) when my GitHub Actions YAML pipeline runs. Not sure if this helps.

Session info

xfun::session_info()
R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 22000), RStudio 2022.2.1.461

Locale:
  LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252    LC_MONETARY=English_Australia.1252
  LC_NUMERIC=C                       LC_TIME=English_Australia.1252    

Package version:
  compiler_4.1.2  graphics_4.1.2  grDevices_4.1.2 stats_4.1.2     tools_4.1.2     utils_4.1.2    
  xfun_0.30   
@cderv
Copy link
Collaborator

cderv commented May 31, 2022

Hi @erikaduan !

There is several things in this issue I think.

A second minor observation is that html documents are also rendered in my output directory despite adding the code below to my report template.

You are explicitly overwriting your YAML header configuration for output by providing a output format function in output_format = github_document() (https://github.com/erikaduan/abs_labour_force_report/blob/907d41d5d066dcdb445c1f233096de8e415a0459/code/03_automate_reports.R#L48). You need to use output_format = github_document(html_preview = FALSE) or use a named format output_format = "github_document", which will tell rmarkdown to look for github_document YAML key for configuration. You can also not provide any format, and the first one in the YAML header will be used.

The absolute file path first generated is my local file path i.e. , which then gets overwritten into

When you render on your local environment which seems to be Windows, the windows absolute path is used. when you render on Github action, you are not using windows but ubuntu so a Linux absolute path scheme is used. Hence the difference. But at the end, the issue is the same, it is using a absolute path.

So what about this absolute file path?

I think you are encountering this issue : #2024
Using output_dir will unfortunately create a absolute path for figure which is not great.

Unfortunately, this is not an easy issue and the paths handling from within rmarkdown::render() is really not ideal. It is usually best to handle directly moving files before and after render. So we don't have a rmarkdown-provided solution right now and I would suggest adapting your workflow to not use those paths argument in render(). Absolute paths and rmarkdown are not playing well.

Several hints:

  • You can use xfun::from_root() to create relative path instead of absolute path. here::here() is great, but it will find your root and then create absolute path by default which is not that portable. xfun::from_root() can make those path relative to your project, or working dir

  • Using fs package can help move files around so that you can render everything in a folder, and then move output as part of your process.

Doing something like this would probably we working as you are expecting

for (i in 1:nrow(params_df)) {
  temp_output <- xfun::from_root("code", "output")
  fs::dir_create(temp_output)
  rmarkdown::render(
    input = xfun::from_root("code", "02_create_report_template.Rmd"),
    output_format = github_document(html_preview = FALSE), 
    params = list(sex = params_df[i, 1],
                  measure = params_df[i, 2]),
    output_file = xfun::from_root(temp_output, glue::glue("{params_df[i, 1]}_{params_df[i, 2]}_report.md"))
  )
  fs::dir_copy(temp_output, xfun::from_root("output"), overwrite = TRUE)
  fs::dir_delete(temp_output)
}

This could even be simplified if you would do all the rendering locally in the code folder (by executing the R script using code/ as working directory e.g using withr::with_dir() or xfun::in_dir() or working_directory yaml config in GHA), you could then simplify the paths. Then moving all the outputs in the right place is not that hard.

I hope it helps

@cderv cderv added duplicate already another issue about this theme: paths path related improvment / issue labels May 31, 2022
@cderv
Copy link
Collaborator

cderv commented May 31, 2022

Duplicate of #2024

@cderv cderv marked this as a duplicate of #2024 May 31, 2022
@erikaduan
Copy link
Author

Thanks so much for solving both questions so quickly @cderv.

The explanations and code solution was extremely helpful. An interesting observation I made was that the code you suggested causes ![](output/all_full-time_report_files...png)<!-- --> to be printed, when ![](/all_full-time_report_files...png)<!-- --> is the desired relative path.

I ended up using your suggestion to use xfun::in_dir() and then (inelegantly) move the rendered files and file dependencies into my ~/output directory.

for (i in 1:nrow(params_df)) {
  # Temporarily change wd to ~/code with xfun::in_dir() and render Rmd
  xfun::in_dir(
    "code", 
    rmarkdown::render(
      input = "02_create_report_template.Rmd",
      output_format = github_document(html_preview = FALSE), 
      params = list(sex = params_df[i, 1],
                    measure = params_df[i, 2]),
      output_file = glue::glue("{params_df[i, 1]}_{params_df[i, 2]}_report.md")
    )
  )
}

# Move output files from ~/code to ~/output
# Extract all files which do not end in .R or .Rmd
code_files <- grep("\\.R|(Rmd)$",
                   fs::dir_ls(xfun::from_root("code")),
                   invert = TRUE,
                   value = TRUE)

# Create location of output files
output_files <- gsub("code/", "output/", code_files)

# Move output files into ~/output 
fs::file_move(code_files, output_files)

@cderv
Copy link
Collaborator

cderv commented May 31, 2022

An interesting observation I made was that the code you suggested causes to be printed, when is the desired relative path.

Oh you're right. We are moving the files also. Interesting that it does not get correctly changed - I'll have a look.

But xfun::in_dir() is definitely a better fit here and I would stick to that.

code_files <- grep("\.R|(Rmd)$", fs::dir_ls(xfun::from_root("code"))

FYI fs::dir_ls() supports pattern (glob and regex) which should avoid using an external grep. But both works the same.

@github-actions
Copy link

github-actions bot commented Dec 6, 2022

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
duplicate already another issue about this theme: paths path related improvment / issue
Projects
None yet
Development

No branches or pull requests

2 participants