You can get what you are asking for now in R 4.0.0 with
globalCallingHandlers and using the packageConflictError object that
is signaled. This should get you started:

```
options(conflicts.policy = "strict")

packageConflictError

handle_conflicts <- function(e) {
    cat(conditionMessage(e))
    opt <- readline(prompt="1: mask.ok; 2: exclude. Choose: ")
    if (opt == "1")
        conflictRules(e$package, mask.ok = as.character(unlist(e$conflicts)))
    else if (opt == "2")
        conflictRules(e$package, exclude = as.character(unlist(e$conflicts)))
    stop("unresolved conflicts") ## ideal invode a restart here
}

globalCallingHandlers(packageConflictError = handle_conflicts)

library(dplyr)
```

An IDE could provide a more sophisticated interface, like a dialog
allowing separate choices for each conflict. But this is best left up
to the IDE or the user.

The one addition to library that might be worth considering is to
provide a restart for the handler to invoke.

Best,

luke

On Wed, 20 May 2020, Juan Telleria Ruiz de Aguirre wrote:

Dear R Developers,

###
# Context:
###

When managing Search Path Conflicts (See:
https://developer.r-project.org/Blog/public/2019/03/19/managing-search-path-conflicts/index.html),
with:

options(conflicts.policy = "strict")

We get the following behaviour when loading a package (Eg: dplyr):

library(dplyr)
## Error: Conflicts attaching package ‘dplyr’:
##
## The following objects are masked from ‘package:stats’:
##
##     filter, lag
##
## The following objects are masked from ‘package:base’:
##
##     intersect, setdiff, setequal, union

So we would have to solve the conflict by writing:

library(dplyr,
       mask.ok = c("filter", "lag",
                   "intersect", "setdiff", "setequal",
                   "union"))

So my feature request proposals:

###
# Feature Request 1: Interactive Session
###

Would it be possible to raise an input prompt, which asks user for an
action to be taken as regards conflicts?

This would make the package loading process more dynamic when being
loaded for first time in an interactive session (Eg: R Notebook). An
example:

The first time the package is loaded:

options(conflicts.policy = "strict", conflicts.policy.ask = TRUE)

library(dplyr)

Executes iteratively the code, in order to ask the user for action
(See toy example):

opt <- readline(prompt="1: mask.ok; 2: exclude. Choose: ")

if (opt == "1"){

 txt <- sprintf(
   fmt = "conflictRules(pkg = '%s' , mask.ok = '%s')",
   "package.name",
   "variable.name"
 )

 eval(parse(text = txt))

 message(txt)

} else if(opt == "2"){

 txt <- sprintf(
   fmt = "conflictRules(pkg = '%s' , exclude = '%s')",
   "package.name",
   "variable.name"
 )

 eval(parse(text = txt))

 message(txt)

}

And afterwards, a message is printed with the selected
"conflictRules()" Configuration for the dynamic setup.

The user will only have to put the printed pre-configured
"conflictRules()" setup into his code, and when re-executing, the
input prompt asking for action will not be raised back again.

Such behaviour is similar in spirit to how 'conflicted' R package
works, which prints for example, for dplyr::filter :

Error: [conflicted] `filter` found in 2 packages.
Either pick the one you want with `::`
* dplyr::filter
* stats::filter
Or declare a preference with `conflict_prefer()`
* conflict_prefer("filter", "dplyr")
* conflict_prefer("filter", "stats")

Where the user will only have to copy "conflict_prefer("filter",
"dplyr")" and paste it into his script. The difference, is that with:
options(conflicts.policy = "strict", conflicts.policy.ask = TRUE),
such message is printed at package load.

I would put the required code within the library() function with the
following conditional:
...
if (length(conflicts)) {
  if(getOption("conflicts.policy.ask") == TRUE){
     ...
  }
}
...

###
# Feature Request 2: Source Execution
###

Another alternative, which could apply when executing the .R file from
source, would be to suggest the user a default conflictRules() setup:

options(conflicts.policy = "strict")
library(dplyr)

# Error: Conflicts attaching package ‘dplyr’:
#
# The following objects are masked from ‘package:stats’:
#
#     filter, lag
#
# The following objects are masked from ‘package:base’:
#
#     intersect, setdiff, setequal, union
#
# Declare preference with `conflictRules()` before loading:
#     * conflictRules("dplyr", mask.ok = list(stats = TRUE, base = TRUE))
#     * conflictRules("dplyr", mask.ok = list(stats = c("filter",
"lag"), base = c("intersect", "setdiff", "setequal", "union")))
#     * conflictRules("dplyr", exclude = c("filter", "lag",
"intersect", "setdiff", "setequal", "union"))

In this case, the error message would have to be extended with
sensible suggested defaults.

Thanks,
Juan

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
   Actuarial Science
241 Schaeffer Hall                  email:   luke-tier...@uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to