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

Using conflicts_prefer() et al. in .Rprofile no longer works #91

Open
uhkeller opened this issue Aug 22, 2023 · 5 comments
Open

Using conflicts_prefer() et al. in .Rprofile no longer works #91

uhkeller opened this issue Aug 22, 2023 · 5 comments
Labels
feature a feature request or enhancement

Comments

@uhkeller
Copy link

uhkeller commented Aug 22, 2023

Using conflicts_prefer() in an .Rprofile file no longer works, though from the console output it appears to.

I'm sure that it used to work before. Since the last release of {conflicted} was in February and I'm pretty sure it has worked after that for some time, maybe a change in R 4.3.0, or even 4.3.1, is causing this?

Steps to reproduce:

In an empty folder, create an .Rprofile file with the following contents:

# .Rprofile
library(conflicted)
library(dplyr)
conflicts_prefer(dplyr::filter)

Start R in this folder. Output:

R version 4.3.1 (2023-06-16) -- "Beagle Scouts"
[…]
[conflicted] Will prefer dplyr::filter over any other package.

But dplyr::filter is not in fact preferred:

> filter
function (x, filter, method = c("convolution", "recursive"),
[…]
<environment: namespace:stats>

Running the call to conflicts_prefer() again, on the command line or by sourcing .Rprofile, works:

> conflicts_prefer(dplyr::filter)
[conflicted] Removing existing preference.
[conflicted] Will prefer dplyr::filter over any other package.
> filter
function (.data, ..., .by = NULL, .preserve = FALSE)
[…]
<environment: namespace:dplyr>

The same happens when using conflict_prefer() instead.

Edit: sessionInfo() after starting R

> sessionInfo()
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.5.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Luxembourg
tzcode source: internal

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

other attached packages:
[1] dplyr_1.1.2      conflicted_1.2.0

loaded via a namespace (and not attached):
 [1] utf8_1.2.3       R6_2.5.1         fastmap_1.1.1    tidyselect_1.2.0
 [5] magrittr_2.0.3   cachem_1.0.8     glue_1.6.2       tibble_3.2.1
 [9] pkgconfig_2.0.3  memoise_2.0.1    generics_0.1.3   lifecycle_1.0.3
[13] cli_3.6.1        fansi_1.0.4      vctrs_0.6.3      compiler_4.3.1
[17] pillar_1.9.0     rlang_1.1.1
@jennybc
Copy link
Member

jennybc commented Sep 30, 2023

I am able to reproduce what OP reports in a terminal:

[conflicted] Will prefer dplyr::filter over any other package.
> search()
 [1] ".GlobalEnv"         "package:stats"      "package:graphics"  
 [4] "package:grDevices"  "package:utils"      "package:datasets"  
 [7] ".conflicts"         "package:dplyr"      "package:conflicted"
[10] "package:methods"    "Autoloads"          "package:base"      
> filter(mtcars, mpg > 27)
Error: object 'mpg' not found
> dplyr::filter(mtcars, mpg > 27)
                mpg cyl disp  hp drat    wt  qsec vs am gear carb
Fiat 128       32.4   4 78.7  66 4.08 2.200 19.47  1  1    4    1
Honda Civic    30.4   4 75.7  52 4.93 1.615 18.52  1  1    4    2
Toyota Corolla 33.9   4 71.1  65 4.22 1.835 19.90  1  1    4    1
Fiat X1-9      27.3   4 79.0  66 4.08 1.935 18.90  1  1    4    1
Lotus Europa   30.4   4 95.1 113 3.77 1.513 16.90  1  1    5    2

but not in RStudio:

[conflicted] Will prefer dplyr::filter over any other package.
> search()
 [1] ".GlobalEnv"         ".conflicts"         "tools:rstudio"      "package:stats"     
 [5] "package:graphics"   "package:grDevices"  "package:utils"      "package:datasets"  
 [9] "package:dplyr"      "package:conflicted" "package:methods"    "Autoloads"         
[13] "package:base"      
> filter(mtcars, mpg > 27)
                mpg cyl disp  hp drat    wt  qsec vs am gear carb
Fiat 128       32.4   4 78.7  66 4.08 2.200 19.47  1  1    4    1
Honda Civic    30.4   4 75.7  52 4.93 1.615 18.52  1  1    4    2
Toyota Corolla 33.9   4 71.1  65 4.22 1.835 19.90  1  1    4    1
Fiat X1-9      27.3   4 79.0  66 4.08 1.935 18.90  1  1    4    1
Lotus Europa   30.4   4 95.1 113 3.77 1.513 16.90  1  1    5    2

@hadley
Copy link
Member

hadley commented Oct 1, 2023

Here's a minimal reprex:

writeLines(con = ".Rprofile", c(
  "library(dplyr)",
  "conflicted::conflicts_prefer(dplyr::filter)"
))
environment(filter)
#> <environment: namespace:stats>
search()
#>  [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
#>  [4] "package:grDevices" "package:utils"     "package:datasets" 
#>  [7] "package:methods"   "Autoloads"         "tools:callr"      
#> [10] "package:base"

Created on 2023-10-01 with reprex v2.0.2

I thought this might be because this code is run before the stats package is attached, and thus conflicted doesn't find any conflicts. But explicitly loading stats doesn't change anything:

writeLines(con = ".Rprofile", c(
  "library(stats)",
  "library(dplyr)",
  "conflicted::conflicts_prefer(dplyr::filter)"
))
environment(filter)
#> <environment: namespace:stats>
search()
#>  [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
#>  [4] "package:grDevices" "package:utils"     "package:datasets" 
#>  [7] "package:methods"   "Autoloads"         "tools:callr"      
#> [10] "package:base"

Created on 2023-10-01 with reprex v2.0.2

@hadley
Copy link
Member

hadley commented Oct 1, 2023

Oh that's because my reprex isn't actually working; dplyr never gets loaded.

@hadley
Copy link
Member

hadley commented Oct 1, 2023

Ok, better reprex which illustrates that my initial guess at the problem was correct:

dir <- tempfile()
dir.create(dir)

writeLines(con = file.path(dir, ".Rprofile"), c(
  "library(dplyr)",
  "conflicted::conflicts_prefer(dplyr::filter)"
))
setwd(dir)
callr::r(user_profile = TRUE, function() {
  list(env =  environment(filter), search = search())
})
#> $env
#> <environment: namespace:stats>
#> 
#> $search
#>  [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
#>  [4] "package:grDevices" "package:utils"     "package:datasets" 
#>  [7] ".conflicts"        "package:dplyr"     "package:methods"  
#> [10] "Autoloads"         "tools:callr"       "package:base"

Created on 2023-10-01 with reprex v2.0.2

dir <- tempfile()
dir.create(dir)

writeLines(con = file.path(dir, ".Rprofile"), c(
  "library(stats)",
  "library(dplyr)",
  "conflicted::conflicts_prefer(dplyr::filter)"
))
setwd(dir)
callr::r(user_profile = TRUE, function() {
  list(env =  environment(filter), search = search())
})
#> $env
#> <environment: namespace:dplyr>
#> 
#> $search
#>  [1] ".GlobalEnv"        "package:graphics"  "package:grDevices"
#>  [4] "package:utils"     "package:datasets"  ".conflicts"       
#>  [7] "package:dplyr"     "package:stats"     "package:methods"  
#> [10] "Autoloads"         "tools:callr"       "package:base"

Created on 2023-10-01 with reprex v2.0.2

@hadley
Copy link
Member

hadley commented Oct 2, 2023

If dplyr::filter() wasn't likely the most common package affected by this, I'd be tempted to leave it. But since it is, I think conflicted probably needs to detect if it's being called from .Rprofile, and if so, add a hook to run after loading is complete. (.First.sys() attaches each package from getOption("defaultPackages") in order, so could use the attach hook for the last package in that vector)

@hadley hadley added the feature a feature request or enhancement label Oct 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants