2

Let's say I have a feature dataframe, f

f = data.frame(X1 = 1:10,
                X2 = 11:20,
                X3 = 21:30)

And an outcome vector, o

o = 1:10

Is there a way for me to create the following 3 functions based on f's variables -- i.e., glmfun_X1, glmfun_X2, glmfun_X3 -- without writing each one out? e.g., I would rather NOT write out:

glmfun_X1 = function(X, Y) {
  glmout = glm(Y ~ ., data = data.frame(X[,"X1"]))
  return(glmout)
}

glmfun_X2 = function(X, Y) {
  glmout = glm(Y ~ ., data = data.frame(X[,"X2"]))
  return(glmout)
}

glmfun_X3 = function(X, Y) {
  glmout = glm(Y ~ ., data = data.frame(X[,"X3"]))
  return(glmout)
}

I would need the functions to be stored in my global environment, so that the following works:

glmfun_X1(X = f, Y = o)
glmfun_X2(X = f, Y = o)
glmfun_X3(X = f, Y = o)

I tried something using a combination of: this post and this post

glmfun <- function(X, Y) {
  glmout = glm(Y ~ ., data = data.frame(X[,xname]))
  return(glmout)
}


for (i in colnames(f)) {
  assign(x = paste0("glmfun_", i),
         value = glmfun,
         envir = .GlobalEnv)
  body(paste0("glmfun_", i))[[2]][[3]][[3]][[2]][[4]] = i
}

glmfun_X1(X = f, Y = o)
glmfun_X2(X = f, Y = o)
glmfun_X3(X = f, Y = o)

However, this doesn't work because xname isn't able to be changed within each function to "X1", "X2", and "X3", respectively, using the body function and a for-loop (I tried lapply, as well, but thought a for-loop would provide a clearer illustration. I got the same error using lapply). Note that, individually, this does work:

i = "X1"
body(glmfun_X1)[[2]][[3]][[3]][[2]][[4]] = i # this works

Any help would be much appreciated!

Maria
  • 31
  • 4
  • and why would you create a static function? You should consider running the models and storing the objects in a list. No need of the functions – Onyambu Jul 18 '23 at 17:35
  • I need to have the static functions to pass into an ensemble learner – Maria Jul 18 '23 at 17:38
  • You do not need static functions. You need one function. Ensure to pass the correct arguments into the function – Onyambu Jul 18 '23 at 17:42
  • purr:walk could be used to create partials – user12256545 Jul 18 '23 at 17:48
  • @user12256545 might you be able to show me what you mean? I tried using purr:walk, but from what I understand that can modify what's being passed into the function, not the function itself (i.e., the body of the function)...but I may be mistaken! – Maria Jul 18 '23 at 20:08

1 Answers1

1

Easiest solution would be to use a for-loop and a eval-parse routine.


f = data.frame(X1 = 1:10,
               X2 = 11:20,
               X3 = 21:30)


for (i in names(f)) {
  eval(parse(text=paste0("glmfun_",i,"<-function(X, Y) {glm(Y ~ .,data=data.frame(X[,'",i,"']))}")))
}

i removed the return statement to make it more concise.

user12256545
  • 2,755
  • 4
  • 14
  • 28