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

sjPlot::tab_model() file parameter ignored if function runs inside a targets pipeline #285

Closed
gorkang opened this issue Jan 28, 2021 · 1 comment
Assignees

Comments

@gorkang
Copy link

gorkang commented Jan 28, 2021

Prework

  • [ x ] Read and agree to the code of conduct and contributing guidelines.
  • [ x ] Confirm that your issue is most likely a genuine bug in targets and not a known limitation or usage error.
  • [ x ] If there is already a relevant issue, whether open or closed, comment on the existing thread instead of posting a new issue.
  • [ x ] Post a minimal reproducible example like this one so the maintainer can troubleshoot the problems you identify. A reproducible example is:
    • [ x ] Runnable: post enough R code and data so any onlooker can create the error on their own computer.
    • [ x ] Minimal: reduce runtime wherever possible and remove complicated details that are irrelevant to the issue at hand.
    • [ x ] Readable: format your code according to the tidyverse style guide.

Description

The sjPlot::tab_model() function has a file parameter that allows you to save a nice .html table of your model results. But when running it inside a {targets} pipeline, the file parameter is ignored and no file is saved.

The saving behavior is triggered when we do tar_read(table_save) or tar_load(table_save); table_save.

I would expect the file to be created when running the pipeline with tar_make() with no further steps.

Please, let me know if you think I should report this in the {sjPlot} package instead of here.

Below a reproducible example. Given it involves creating files, I could not manage to do a proper reprex.

Reproducible example

This is the standard (expected) behavior for the table_save target. You input a model, and if the file parameter is there, it creates a file:

sjPlot::tab_model(lme4::lmer(year ~ displ + (1|manufacturer), data = ggplot2::mpg), file = "TABLE_standard.html")
file.exists("TABLE_standard.html")
# [1] TRUE
file.remove("TABLE_standard.html")
# [1] TRUE

But if the sjPlot::tab_model(model, file = "TABLE_targets.html") code runs inside {targets}, the file parameter is ignored.

library(targets)

tar_script({
  
  library(targets)
  options(crayon.enabled = FALSE)
  tar_option_set(packages = c("targets", "ggplot2", "lme4", "sjPlot"))

  list(
    tar_target(model, lme4::lmer(year ~ displ + (1|manufacturer), data = ggplot2::mpg)),
    tar_target(table_save, sjPlot::tab_model(model, file = "TABLE_targets.html"))
  )
})

tar_make()

file.exists("TABLE_targets.html") # File not saved
# [1] FALSE
tar_load(table_save); length(table_save) # Although table_save is there
# [1] 6
file.exists("TABLE_targets.html") # Just to be sure, file still not there
# [1] FALSE

But, if we take a look, the file is created

table_save
file.exists("TABLE_targets.html")
# [1] TRUE
file.remove("TABLE_targets.html")
# [1] TRUE

Also, if we read it, it is saved

tar_read(table_save)
file.exists("TABLE_targets.html")
# [1] TRUE
file.remove("TABLE_targets.html")
# [1] TRUE

Diagnostic information


> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.1 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=es_CL.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=es_CL.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=es_CL.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=es_CL.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] targets_0.0.2.9000

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.6          mvtnorm_1.1-1       lattice_0.20-41     tidyr_1.1.2         ps_1.5.0            zoo_1.8-8           assertthat_0.2.1    digest_0.6.27      
 [9] R6_2.5.0            backports_1.2.1     reprex_1.0.0        evaluate_0.14       coda_0.19-4         highr_0.8           ggplot2_3.3.3       pillar_1.4.7       
[17] rlang_0.4.10        multcomp_1.4-15     rstudioapi_0.13     minqa_1.2.4         data.table_1.13.6   performance_0.6.1.1 callr_3.5.1         nloptr_1.2.2.2     
[25] Matrix_1.3-2        effectsize_0.4.3    rmarkdown_2.6       styler_1.3.2        ggeffects_1.0.1     splines_4.0.3       lme4_1.1-26         statmod_1.4.35     
[33] stringr_1.4.0       igraph_1.2.6        munsell_0.5.0       sjPlot_2.8.7        broom_0.7.3         compiler_4.0.3      modelr_0.1.8        xfun_0.20          
[41] pkgconfig_2.0.3     parameters_0.11.0   clipr_0.7.1         htmltools_0.5.1.1   insight_0.12.0      tidyselect_1.1.0    tibble_3.0.5        codetools_0.2-18   
[49] fansi_0.4.2         withr_2.4.1         crayon_1.3.4        dplyr_1.0.3         MASS_7.3-53         sjmisc_2.8.6        grid_4.0.3          nlme_3.1-151       
[57] xtable_1.8-4        gtable_0.3.0        lifecycle_0.2.0     DBI_1.1.1           magrittr_2.0.1      bayestestR_0.8.2    scales_1.1.1        stringi_1.5.3      
[65] estimability_1.3    cli_2.2.0           fs_1.5.0            snakecase_0.11.0    ellipsis_0.3.1      generics_0.1.0      vctrs_0.3.6         boot_1.3-26        
[73] sandwich_3.0-0      sjlabelled_1.1.7    TH.data_1.0-10      tools_4.0.3         glue_1.4.2          purrr_0.3.4         sjstats_0.18.1      emmeans_1.5.3      
[81] processx_3.4.5      survival_3.2-7      yaml_2.2.1          colorspace_2.0-0    knitr_1.31         
@wlandau
Copy link
Member

wlandau commented Jan 28, 2021

Oddly enough, sjPlot::tab_model() does not actually write a file. Instead, it returns an sjPlot object whose print() method actually does the writing. When the table runs in a target, it skips the interactive print-out and thus no file is written.

Personally, I find this behavior misleading and recommend filing an issue in the sjPlot package.

> sjPlot:::print.sjTable
function (x, ...) 
{
    if (!is.null(x$file)) {
        write(x$knitr, file = x$file)
    }
    else {
        x$page.complete <- replace_umlauts(x$page.complete)
        htmlFile <- tempfile(fileext = ".html")
        write(x$page.complete, file = htmlFile)
        viewer <- getOption("viewer")
        if (x$viewer && !is.null(viewer)) {
            viewer(htmlFile)
        }
        else {
            utils::browseURL(htmlFile)
        }
    }
}
<bytecode: 0x7fc28ce72df8>
<environment: namespace:sjPlot>

As a workaround, you can call the print method yourself in the target. If you want the file, I also recommend setting format = "file" so the output file is tracked for changes and automatically rebuilt if corrupted.

library(targets)
tar_script({
  options(crayon.enabled = FALSE)
  tar_option_set(
    packages = c("targets", "ggplot2", "lme4", "sjPlot")
  )
  
  save_table <- function(model, path) {
    print(sjPlot::tab_model(model, file = path))
    path
  }
  
  list(
    tar_target(model, lme4::lmer(year ~ displ + (1|manufacturer), data = ggplot2::mpg)),
    tar_target(table_save, save_table(model, "your_table.html"), format = "file")
  )
})

tar_make()
#> ● run target model
#> boundary (singular) fit: see ?isSingular
#> ● run target table_save
#> ● end pipeline

webshot::webshot("your_table.html")

Created on 2021-01-28 by the reprex package (v0.3.0)

@wlandau wlandau closed this as completed Jan 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants