I have a dependent variable name list as
depend<-c('a', 'b', 'c')
And I have a formula for regression model can be defined as
1_equ<-d~e
I would like to automatically switch the dependent variable of that formula by using update.
I have tried
for ( i in depend) {
equ_name<-assign(paste0("1_equ_", i), depend[i])
equ_name<-update(1_equ, paste(depend[i]) ~ .)
}
Seems like it does not work, it only extract the string, but could not switch the variable.
The print results are
chr NA
I would like three outpus:
1_equ_a: a~e
1_equ_b: b~e
1_equ_c: c~e
CodePudding user response:
It would need the "~ ."
in quotes along with loop over the sequence of 'vector' elements and as the object name starts with a digit, use backquotes around it
`1_equ` <- d ~ e
for ( i in seq_along(depend)) {
nm1 <- paste0("1_equ_", depend[i])
assign(nm1, update(`1_equ`, paste(depend[i], "~ .")))
}
-output
> `1_equ_a`
a ~ e
> `1_equ_b`
b ~ e
> `1_equ_c`
c ~ e
CodePudding user response:
Solution 1: construct a formula manually using call
You can do this without string processing with paste
by manually constructing a formula object from symbols using call
:
depend <- c("a", "b", "c")
fmla <- d ~ x y z
print(fmla)
for (depvar in depend) {
fmla <- update(fmla, call("~", as.symbol(depvar), as.symbol(".")))
print(fmla)
}
# d ~ x y z
# a ~ x y z
# b ~ x y z
# c ~ x y z
And this can be wrapped up nicely in a function:
replace_dependent <- function(fmla, new_var) {
pattern <- call("~", as.symbol(new_var), as.symbol("."))
update(fmla, pattern)
}
depend <- c("a", "b", "c")
fmla <- d ~ x y z
print(fmla)
for (depvar in depend) {
fmla <- replace_dependent(fmla, depvar)
print(fmla)
}
# d ~ x y z
# a ~ x y z
# b ~ x y z
# c ~ x y z
I personally much prefer working with call
and other "syntactic" objects, instead of constructing and parsing strings.
Solution 2: use reformulate
An even tidier solution was suggested by IRTFM in the comments: use reformulate
.
extract_term_labels <- function(fmla) {
attr(terms(fmla), "term.labels")
}
replace_dependent <- function(fmla, new_var) {
reformulate(extract_term_labels(fmla), new_var, env = parent.frame(2))
}
depend <- c("a", "b", "c")
fmla <- d ~ x y z
print(fmla)
for (depvar in depend) {
fmla <- replace_dependent(fmla, depvar)
print(fmla)
}
# d ~ x y z
# a ~ x y z
# b ~ x y z
# c ~ x y z
Note the use of env = parent.frame(2)
to prevent accidentally creating a closure over the internal environment of the replace_dependent()
function.