Skip to content
Prev 61483 / 63421 Next

[WARNING: POTENTIAL FORGED EMAIL] Augment base::replace(x, list, value) to allow list= to be a predicate?

Dear All,

Following up on this, I was wondering whether it might be possible to
get a disposition from R developers.

I did find a way to produce a similar effect reasonably concisely using
call alchemy and lazy evaluation. The following function grabs the
specified arguments in the function whose argument it is, applies the
specified function to them, and returns the result. I am not sure if it
correctly handles all possible cases, particularly when nonstandard
evaluation and functions with side-effects are involved.

.af. <- function(...){
  if(is.numeric(arg1 <- ...elt(1)) || is.character(arg1)){ # By position or name
    i <- arg1
    f <- ...elt(2L)
    g <- \(x, dummy1, dummy2, ...) f(x, ...) # Eat 2 arguments in ... .
  }else{ # First argument (the default)
    i <- 1L
    f <- arg1
    g <- \(x, dummy, ...) f(x, ...) # Eat 1 argument in ... .
  }

  sys.function(1L) |> formals() |> names() |>
    setNames(nm=_) |> (`[`)(i) |> get(sys.frame(1L)) |>
    g(...)
}

# Examples:

c(1,2,NA,3) |> replace(.af.(is.na), 0) # First argument

1:5 |> replace(.af.(`>`, 3), 0) # Function of multiple arguments

1:5 |> ifelse(.af.(2, `>`, 3), yes=_, 0) # Specify position of referenced argument

1:5 |> ifelse(.af.("yes", `>`, 3), yes=_, 0) # Specify name of referenced argument

It may also make sense to have hard-coded versions of this for common cases, e.g.,

.a2f. <- function(...) .af.(2L, ...)

I am not sure how readable or concise this is in practice, and I don't
think this should go into R proper, but would anyone else use it if I
put something like this in a package?

				Best Regards,
				Pavel
On Sat, 2023-03-04 at 00:21 +0000, r-devel-bounces at r-project.org wrote: