[Rd] Augment base::replace(x, list, value) to allow list= to be a predicate?
Steve Martin
@tevem@rt|n041 @end|ng |rom gm@||@com
Wed Mar 8 03:41:29 CET 2023
That's an interesting example, as it's conceptually similar to what
Pavel is proposing, but structurally different. gsubfn() is more
complicated than a simple switch in the body of the function, and
wouldn't work well as an anonymous function.
Multiple dispatch can nicely encompass both of these cases. For replace(),
library(S7)
replace <- new_generic("replace", c("x", "list"), function(x, list,
values, ...) {
S7_dispatch()
})
method(replace, list(class_any, class_any)) <- base::replace
method(replace, list(class_any, class_function)) <- function(x, list,
values, ...) {
replace(x, list(x, ...), values)
}
x <- c(1 ,2, NA, 3)
replace(x, is.na(x), 0)
[1] 1 2 0 3
replace(x, is.na, 0)
[1] 1 2 0 3
And for gsub(),
gsub <- new_generic("gsub", c("pattern", "replacement"),
function(pattern, replacement, x, ...) {
S7_dispatch()
})
method(gsub, list(class_character, class_character)) <- base::gsub
# My quick-and-dirty implementation as an example
method(gsub, list(class_character, class_function)) <-
function(pattern, replacement, x) {
m <- regexpr(pattern, x)
res <- replacement(regmatches(x, m))
mapply(gsub, pattern, as.character(res), x, USE.NAMES = FALSE)
}
gsub("^..", toupper, c("abc", "xyz"))
[1] "ABc" "XYz"
But this isn't a simple change to replace() anymore, and I may just be
spending too much time tinkering with Julia.
Steve
On Tue, 7 Mar 2023 at 07:34, Gabor Grothendieck <ggrothendieck using gmail.com> wrote:
>
> This could be extended to sub and gsub as well which gsubfn in the
> gusbfn package already does:
>
> library(gsubfn)
> gsubfn("^..", toupper, c("abc", "xyz"))
> ## [1] "ABc" "XYz"
>
> On Fri, Mar 3, 2023 at 7:22 PM Pavel Krivitsky <p.krivitsky using unsw.edu.au> wrote:
> >
> > Dear All,
> >
> > Currently, list= in base::replace(x, list, value) has to be an index
> > vector. For me, at least, the most common use case is for list= to be
> > some simple property of elements of x, e.g.,
> >
> > x <- c(1,2,NA,3)
> > replace(x, is.na(x), 0)
> >
> > Particularly when using R pipes, which don't allow multiple
> > substitutions, it would simplify many of such cases if list= could be a
> > function that returns an index, e.g.,
> >
> > replace <- function (x, list, values, ...) {
> > # Here, list() refers to the argument, not the built-in.
> > if(is.function(list)) list <- list(x, ...)
> > x[list] <- values
> > x
> > }
> >
> > Then, the following is possible:
> >
> > c(1,2,NA,3) |> replace(is.na, 0)
> >
> > Any thoughts?
> > Pavel
> > ______________________________________________
> > R-devel using r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
>
> --
> Statistics & Software Consulting
> GKX Group, GKX Associates Inc.
> tel: 1-877-GKX-GROUP
> email: ggrothendieck at gmail.com
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list