Gabor Grothendieck
2023-Mar-07 12:33 UTC
[Rd] Augment base::replace(x, list, value) to allow list= to be a predicate?
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 at 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 at 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
Steve Martin
2023-Mar-08 02:41 UTC
[Rd] Augment base::replace(x, list, value) to allow list= to be a predicate?
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 at 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 at 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 at 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 at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Possibly Parallel Threads
- Augment base::replace(x, list, value) to allow list= to be a predicate?
- Augment base::replace(x, list, value) to allow list= to be a predicate?
- Spurious warning in as.data.frame.factor()
- Augment base::replace(x, list, value) to allow list= to be a predicate?
- Spurious warning in as.data.frame.factor()