Hello,
How does one specify a formula to lm inside a function (with variable
names not known in advance) and have the formula appear explicitly in
the output?
For example,
f <- function(d) {
in.model <- sample(c(0,1), ncol(d)-1, replace=T)
current.model <- lm(paste(names(d)[1], "~",
paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse= "+")),
data=d) #***
return(current.model)
}
x1 <- rnorm(50,0,1)
x2 <- rnorm(50,0,1)
x3 <- rnorm(50,0,1)
x4 <- rnorm(50,0,1)
y <- rnorm(50,0,1)
d <- data.frame(y, x1, x2, x3, x4)
f(d)
Call:
lm(formula = paste(names(d)[1], "~",
paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse = "+")),
data = d)
Coefficients:
(Intercept) x3 x4
-0.1087 0.2830 0.1024
How can I specify the formula in the line marked *** so that the
output will show "formula = y ~ x3 + x4" instead of "formula
paste..."?
Thanks for any help you can give.
Regards,
Mark
--
Mark Seeto
Statistician
National Acoustic Laboratories
A Division of Australian Hearing
Here is one way.
f <- function(d) {
y <- names(d)[1]
xs <- names(d)[-1]
nx <- length(xs)
xs <- sort(sample(xs, sample(1:nx, 1)))
form <- as.formula(paste(y, "~", paste(xs,
collapse="+")))
Call <- substitute(lm(FORM, data = d), list(FORM = form))
eval(Call)
}
d <- within(data.frame(y = rnorm(50)), {
x1 <- rnorm(50)
x2 <- rnorm(50)
x3 <- rnorm(50)
x4 <- rnorm(50)
})
f(d)
-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org]
On Behalf Of Mark Seeto
Sent: Thursday, 10 June 2010 2:18 PM
To: r-help at r-project.org
Subject: [R] Specifying formula inside a function
Hello,
How does one specify a formula to lm inside a function (with variable
names not known in advance) and have the formula appear explicitly in
the output?
For example,
f <- function(d) {
in.model <- sample(c(0,1), ncol(d)-1, replace=T)
current.model <- lm(paste(names(d)[1], "~",
paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse= "+")),
data=d) #***
return(current.model)
}
x1 <- rnorm(50,0,1)
x2 <- rnorm(50,0,1)
x3 <- rnorm(50,0,1)
x4 <- rnorm(50,0,1)
y <- rnorm(50,0,1)
d <- data.frame(y, x1, x2, x3, x4)
f(d)
Call:
lm(formula = paste(names(d)[1], "~",
paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse = "+")),
data = d)
Coefficients:
(Intercept) x3 x4
-0.1087 0.2830 0.1024
How can I specify the formula in the line marked *** so that the
output will show "formula = y ~ x3 + x4" instead of "formula
paste..."?
Thanks for any help you can give.
Regards,
Mark
--
Mark Seeto
Statistician
National Acoustic Laboratories
A Division of Australian Hearing
______________________________________________
R-help at r-project.org mailing list
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.
Hello,> How does one specify a formula to lm inside a function (with variable > names not known in advance) and have the formula appear explicitly in > the output? > > For example, > > f <- function(d) { > in.model <- sample(c(0,1), ncol(d)-1, replace=T) > current.model <- lm(paste(names(d)[1], "~", > paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse= "+")), > data=d) #*** > return(current.model) > } > x1 <- rnorm(50,0,1) > x2 <- rnorm(50,0,1) > x3 <- rnorm(50,0,1) > x4 <- rnorm(50,0,1) > y <- rnorm(50,0,1) > d <- data.frame(y, x1, x2, x3, x4) > f(d) > > Call: > lm(formula = paste(names(d)[1], "~", > paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse = "+")), > data = d) > > Coefficients: > (Intercept) x3 x4 > -0.1087 0.2830 0.1024 > > How can I specify the formula in the line marked *** so that the > output will show "formula = y ~ x3 + x4" instead of "formula > paste..."? >Well, there could very well be some tricks you can pull with ?substitute, or others, but I can't seem to figure it out. Instead of tricks, it might be easier/clearer to assign a class to your object, say 'test', and write a print method for that based on print.lm. There very well may be drawbacks to this that I am not realizing :). f <- function(d) { in.model <- sample(c(0,1), ncol(d)-1, replace=TRUE) current.model <- lm(paste(names(d)[1], "~", paste(names(d[2:ncol(d)])[which(in.model == 1)], collapse= "+")), data=d) class(current.model) <- c("test", "lm") current.model } # slight modification to print.lm print.test <- function (x, digits = max(3, getOption("digits") - 3), ...) { cat("\nCall:\n", deparse(x$terms), "\n\n", sep = "") if (length(coef(x))) { cat("Coefficients:\n") print.default(format(coef(x), digits = digits), print.gap = 2, quote = FALSE) } else cat("No coefficients\n") cat("\n") invisible(x) } # should give you what you want... f(d)