Home > database >  Dynamically change dependent variable in formula
Dynamically change dependent variable in formula

Time:11-17

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.

  •  Tags:  
  • r
  • Related