wahani / modules

Modules in R

Home Page:https://cran.r-project.org/package=modules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Import of pipe operator works if importing "magrittr", but not if using "tidyverse"

mpettis opened this issue · comments

In my usual scripts, I do a library(tidyverse) call, and I get things like the magrittr pipe (%>%). But when using modules, if I import("tidyverse"), the pipe operator is not found. However, it does work if i do import("magrittr"). Reprex below.

library(modules)
#> Warning: package 'modules' was built under R version 3.6.3

## Can find the pipe operator if I call magrittr directly
m <- module({
    import("magrittr")
    foo <- function() { 1:3 %>% mean() }
})

m$foo()
#> [1] 2


## Cannot find pipe operator if imported via tidyverse package
q <- module({
    import("tidyverse")
    foo <- function() { 1:3 %>% mean() }
})

q$foo()
#> Error in 1:3 %>% mean(): could not find function "%>%"

## Session info
sessioninfo::session_info()
#> - Session info ---------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.6.1 (2019-07-05)
#>  os       Windows 10 x64              
#>  system   x86_64, mingw32             
#>  ui       RTerm                       
#>  language (EN)                        
#>  collate  English_United States.1252  
#>  ctype    English_United States.1252  
#>  tz       America/Chicago             
#>  date     2020-08-06                  
#> 
#> - Packages -------------------------------------------------------------------
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 3.6.1)
#>  backports     1.1.7   2020-05-13 [1] CRAN (R 3.6.3)
#>  broom         0.5.6   2020-04-20 [1] CRAN (R 3.6.3)
#>  cellranger    1.1.0   2016-07-27 [1] CRAN (R 3.6.1)
#>  cli           2.0.2   2020-02-28 [1] CRAN (R 3.6.3)
#>  colorspace    1.4-1   2019-03-18 [1] CRAN (R 3.6.1)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.6.1)
#>  DBI           1.1.0   2019-12-15 [1] CRAN (R 3.6.3)
#>  dbplyr        1.4.3   2020-04-19 [1] CRAN (R 3.6.3)
#>  digest        0.6.25  2020-02-23 [1] CRAN (R 3.6.3)
#>  dplyr         1.0.0   2020-05-29 [1] CRAN (R 3.6.3)
#>  ellipsis      0.3.0   2019-09-20 [1] CRAN (R 3.6.1)
#>  evaluate      0.14    2019-05-28 [1] CRAN (R 3.6.1)
#>  fansi         0.4.1   2020-01-08 [1] CRAN (R 3.6.3)
#>  forcats       0.5.0   2020-03-01 [1] CRAN (R 3.6.3)
#>  fs            1.4.1   2020-04-04 [1] CRAN (R 3.6.3)
#>  generics      0.0.2   2018-11-29 [1] CRAN (R 3.6.1)
#>  ggplot2       3.3.0   2020-03-05 [1] CRAN (R 3.6.3)
#>  glue          1.4.1   2020-05-13 [1] CRAN (R 3.6.3)
#>  gtable        0.3.0   2019-03-25 [1] CRAN (R 3.6.1)
#>  haven         2.2.0   2019-11-08 [1] CRAN (R 3.6.1)
#>  highr         0.8     2019-03-20 [1] CRAN (R 3.6.1)
#>  hms           0.5.3   2020-01-08 [1] CRAN (R 3.6.3)
#>  htmltools     0.4.0   2019-10-04 [1] CRAN (R 3.6.1)
#>  httr          1.4.1   2019-08-05 [1] CRAN (R 3.6.1)
#>  jsonlite      1.6.1   2020-02-02 [1] CRAN (R 3.6.3)
#>  knitr         1.28    2020-02-06 [1] CRAN (R 3.6.3)
#>  lattice       0.20-41 2020-04-02 [1] CRAN (R 3.6.3)
#>  lifecycle     0.2.0   2020-03-06 [1] CRAN (R 3.6.3)
#>  lubridate     1.7.8   2020-04-06 [1] CRAN (R 3.6.3)
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 3.6.1)
#>  modelr        0.1.7   2020-04-30 [1] CRAN (R 3.6.3)
#>  modules     * 0.8.0   2019-02-10 [1] CRAN (R 3.6.3)
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 3.6.1)
#>  nlme          3.1-147 2020-04-13 [1] CRAN (R 3.6.3)
#>  pillar        1.4.4   2020-05-05 [1] CRAN (R 3.6.3)
#>  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 3.6.1)
#>  purrr         0.3.4   2020-04-17 [1] CRAN (R 3.6.3)
#>  R6            2.4.1   2019-11-12 [1] CRAN (R 3.6.1)
#>  Rcpp          1.0.4.6 2020-04-09 [1] CRAN (R 3.6.3)
#>  readr         1.3.1   2018-12-21 [1] CRAN (R 3.6.1)
#>  readxl        1.3.1   2019-03-13 [1] CRAN (R 3.6.1)
#>  reprex        0.3.0   2019-05-16 [1] CRAN (R 3.6.1)
#>  rlang         0.4.6   2020-05-02 [1] CRAN (R 3.6.3)
#>  rmarkdown     2.1     2020-01-20 [1] CRAN (R 3.6.3)
#>  rvest         0.3.5   2019-11-08 [1] CRAN (R 3.6.1)
#>  scales        1.1.1   2020-05-11 [1] CRAN (R 3.6.3)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.6.1)
#>  stringi       1.4.6   2020-02-17 [1] CRAN (R 3.6.2)
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 3.6.1)
#>  tibble        3.0.1   2020-04-20 [1] CRAN (R 3.6.3)
#>  tidyr         1.0.3   2020-05-07 [1] CRAN (R 3.6.3)
#>  tidyselect    1.1.0   2020-05-11 [1] CRAN (R 3.6.3)
#>  tidyverse     1.3.0   2019-11-21 [1] CRAN (R 3.6.3)
#>  vctrs         0.3.0   2020-05-11 [1] CRAN (R 3.6.3)
#>  withr         2.2.0   2020-04-20 [1] CRAN (R 3.6.3)
#>  xfun          0.13    2020-04-13 [1] CRAN (R 3.6.3)
#>  xml2          1.3.2   2020-04-23 [1] CRAN (R 3.6.3)
#>  yaml          2.2.1   2020-02-01 [1] CRAN (R 3.6.3)
#> 
#> [1] C:/Users/IRINZN/Documents/R/R-3.6.1/library

Created on 2020-08-06 by the reprex package (v0.3.0)

Thanks for taking the time to report this issue.

The modules package will import all names/objects that are exported by a package. So using dplyr in your example will work, because dplyr correctly re-exports the pipe operator. You can see how that works here: https://github.com/tidyverse/dplyr/blob/f08991955f7bb76ad7f7f2364dbe90699a123d68/R/utils.r#L3

The package tidyverse does not re-export any objects; as far as I can tell. It also circumvents Rs build-in mechanism for attaching dependencies - the Depends field in the Description of the package; see: https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Package-Dependencies - that may have presented a way for a fix for your use-case. Instead, in the tidyverse package a custom function is being called (https://github.com/tidyverse/tidyverse/blob/8a0bb998e92fb61339d555f22d8bf7314c625700/R/attach.R#L18) when you attach the tidyverse package (https://github.com/tidyverse/tidyverse/blob/8a0bb998e92fb61339d555f22d8bf7314c625700/R/zzz.R#L1). Attaching is nothing else then calling library. There you find the lines where library is called and attaches all other tidyverse packages as a side-effect.

I do not see any sane way to figure out which objects need to be imported from the outside. At the same time I would like to encourage you to be more explicit when importing objects into a module. It was one of the design goals of the modules package to be able to import single objects from a package. Nonetheless, here is how I would hack my way around it, when I really do not want to spell it out:

imports <- modules::module({

  tidyverse <- function(where = parent.frame()) {
    ## Import all packages that are usually attached by the tidyverse package.
    ## where (environment) the environment where you want attach the pkgs.
    ##   Usually the calling environment of this function.
    for (pkg in tidyverse:::core) {
      suppressPackageStartupMessages(
        eval(substitute(modules::import(pkg)), envir = where)
      )
    }
  }

})

q <- modules::module({
  use(imports)$tidyverse()
  foo <- function() { 1:3 %>% mean() }
})


q$foo()

You may want to put the imports module into a separate file, so you do not have to care about it anymore; in that case just refer to the filename in use.

Hope this is somehow helpful.

Thank you, this was helpful! I was ok explicitly importing magrittr, but I just wanted to report this in case this wasn't intended behavior for, say, tidyverse. I'm good now, and your comment above was helpful beyond the original question. Thank you.