R:在变量列表中使用 gam::gam 和 lapply

R: Using gam::gam with lapply on list of variables

我想将不同的逻辑模型应用于数据框中的变量列表。函数 glm()lme4::glmer() 以及 mgcv::gam() 都可以正常工作。但是函数 gam::gam() 我不能用 lapply.

示例:

n <- 1000                                                                                            
y <- rbinom(n,1,0.2)                                                                                 
x1 <- rnorm(n)                                                                                       
x2 <- rnorm(n)                                                                                       
xlist  <- list("x1", "x2")                                                                           
df <- data.frame(y, x1, x2)                                                                          

library(gam)

#doesn't work                                                                                                     
gam_list <- lapply(xlist, function(x){                                                              
  gam::gam(substitute(y ~ s(i), list(i = as.name(x))), data = df, family = binomial)                
})      
#Error in terms.default(formula, gam.slist, data = data) :
#no terms component nor attribute

gam <- gam(y ~ s(x1), data = df, family =binomial)

有任何解决此错误的想法吗?

您可以在这里使用 get,如下所示,它应该可以工作,或者 eval(parse(text=x)) 而不是 get:

gam_list <- lapply(xlist, function(x){                                                              
  gam::gam(y ~ s(get(x)), data = df, family = binomial)                
})   

输出:

[[1]]
Call:
gam::gam(formula = y ~ s(get(x)), family = binomial, data = df)

Degrees of Freedom: 999 total; 995 Residual
Residual Deviance: 1010.515 

[[2]]
Call:
gam::gam(formula = y ~ s(get(x)), family = binomial, data = df)

Degrees of Freedom: 999 total; 994.9997 Residual
Residual Deviance: 1011.254 

您还可以将字符串转换为公式。

gam_list <- lapply(xlist, function(x) 
            gam::gam(as.formula(sprintf('y~s(%s)', x)), data = df, family = binomial))

gam_list

#[[1]]
#Call:
#gam::gam(formula = as.formula(sprintf("y~s(%s)", x)), family = binomial, data = df)

#Degrees of Freedom: 999 total; 995 Residual
#Residual Deviance: 984.8362 

#[[2]]
#Call:
#gam::gam(formula = as.formula(sprintf("y~s(%s)", x)), family = binomial, data = df)

#Degrees of Freedom: 999 total; 995.0002 Residual
#Residual Deviance: 985.5421