Suppose I have a formula like this:
f <- y ~ qss(x, lambda = lambdas[1]) + qss(z, lambdas[2]) + s
I?d like a function, g(lambdas, f) that would take g(c(2,3), f) and produce the new
formula:
y ~ qss(x, lambda = 2) + qss(z, 3) + s
For only two qss terms I have been using
g <- function(lambdas, f){
F <- deparse(f)
F <- gsub("lambdas\\[1\\]",lambdas[1],F)
F <- gsub("lambdas\\[2\\]",lambdas[2],F)
formula(F)
}
but this is ugly and doesn?t extend nicely to more qss terms. Isn?t there some
bquote() magic that can be invoked? Or something else entirely?
formula mungeing
4 messages · Roger Koenker, Gabor Grothendieck, Bert Gunter
Recursively walk the formula performing the replacement:
g <- function(e, ...) {
if (length(e) > 1) {
if (identical(e[[2]], as.name(names(list(...))))) {
e <- eval(e, list(...))
}
if (length(e) > 1) for (i in 1:length(e)) e[[i]] <- Recall(e[[i]], ...)
}
e
}
g(f, lambdas = 2:3)
## y ~ qss(x, lambda = 2L) + qss(z, 3L) + s
On Fri, Oct 23, 2020 at 9:33 AM Koenker, Roger W <rkoenker at illinois.edu> wrote:
Suppose I have a formula like this:
f <- y ~ qss(x, lambda = lambdas[1]) + qss(z, lambdas[2]) + s
I?d like a function, g(lambdas, f) that would take g(c(2,3), f) and produce the new
formula:
y ~ qss(x, lambda = 2) + qss(z, 3) + s
For only two qss terms I have been using
g <- function(lambdas, f){
F <- deparse(f)
F <- gsub("lambdas\\[1\\]",lambdas[1],F)
F <- gsub("lambdas\\[2\\]",lambdas[2],F)
formula(F)
}
but this is ugly and doesn?t extend nicely to more qss terms. Isn?t there some
bquote() magic that can be invoked? Or something else entirely?
______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
Thanks, Gabor! Very elegant!
On Oct 23, 2020, at 4:15 PM, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
Recursively walk the formula performing the replacement:
g <- function(e, ...) {
if (length(e) > 1) {
if (identical(e[[2]], as.name(names(list(...))))) {
e <- eval(e, list(...))
}
if (length(e) > 1) for (i in 1:length(e)) e[[i]] <- Recall(e[[i]], ...)
}
e
}
g(f, lambdas = 2:3)
## y ~ qss(x, lambda = 2L) + qss(z, 3L) + s
On Fri, Oct 23, 2020 at 9:33 AM Koenker, Roger W <rkoenker at illinois.edu> wrote:
Suppose I have a formula like this:
f <- y ~ qss(x, lambda = lambdas[1]) + qss(z, lambdas[2]) + s
I?d like a function, g(lambdas, f) that would take g(c(2,3), f) and produce the new
formula:
y ~ qss(x, lambda = 2) + qss(z, 3) + s
For only two qss terms I have been using
g <- function(lambdas, f){
F <- deparse(f)
F <- gsub("lambdas\\[1\\]",lambdas[1],F)
F <- gsub("lambdas\\[2\\]",lambdas[2],F)
formula(F)
}
but this is ugly and doesn?t extend nicely to more qss terms. Isn?t there some
bquote() magic that can be invoked? Or something else entirely?
______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
-- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
I can't compete with Gabor's "elegant" solution, but I don't understand why
your original "ugly" approach doesn't work.
g <- function(lambdas, f){
z <- as.character(f)
for(i in seq_along(lambdas))
z[3]<- sub(paste0("lambdas[", i, "]"), lambdas[i], z[3], fixed =
TRUE)
formula(paste0(z[c(2,1,3)], collapse = " "))
}
f <- y ~ qss(x, lambda = lambdas[1]) + qss(z, lambdas[2]) + s g(1:2, f)
y ~ qss(x, lambda = 1) + qss(z, 2) + s <environment: 0x7f930e768598>
f <- y ~ qss(x, lambda = lambdas[1]) + qss(z, lambdas[2]) +
+ qss(z,lambdas[3]) + s
g(3:1, f)
y ~ qss(x, lambda = 3) + qss(z, 2) + qss(z, 1) + s <environment: 0x7f930e7404f0> Is there maybe a problem with the environment of the created formula? Or have I misunderstood what you wanted? Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Fri, Oct 23, 2020 at 6:33 AM Koenker, Roger W <rkoenker at illinois.edu> wrote:
Suppose I have a formula like this:
f <- y ~ qss(x, lambda = lambdas[1]) + qss(z, lambdas[2]) + s
I?d like a function, g(lambdas, f) that would take g(c(2,3), f) and
produce the new
formula:
y ~ qss(x, lambda = 2) + qss(z, 3) + s
For only two qss terms I have been using
g <- function(lambdas, f){
F <- deparse(f)
F <- gsub("lambdas\\[1\\]",lambdas[1],F)
F <- gsub("lambdas\\[2\\]",lambdas[2],F)
formula(F)
}
but this is ugly and doesn?t extend nicely to more qss terms. Isn?t there
some
bquote() magic that can be invoked? Or something else entirely?
______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.