用lappy做循环glm

时间:2016-05-20 12:04:36

标签: r logistic-regression

这是我尝试做的一个例子。

第1步:

创建因变量和自变量组合的列表

a <- list(paste("Sepal.Length ~  Sepal.Width" ) , 
paste("Sepal.Width ~ Sepal.Length" )
)

第2步:

使用lappy函数为步骤#1中列表中的每个元素运行glm,并创建for循环以测试两个不同的参数

param <- c("gaussian" , "Gamma" )
for(i in 1:2) {
print(lapply(a , FUN = function(X) glm(X , data = iris ,family = param[i]    )))}

在第二步中不使用for循环是否有更好的方法来实现这一目标?这是我尝试过的,但它没有用。

a <- 
list(
paste("Sepal.Length ~  Sepal.Width , data = iris , family = "Gaussian" " ) , 
paste("Sepal.Length ~  Sepal.Width , data = iris , family = "Gamma" " ) ,                  
paste("Sepal.Width ~  Sepal.Length , data = iris , family = "Gaussian" " ) ,
paste("Sepal.Width ~  Sepal.Length , data = iris , family = "Gamma" " ) 
)

lapply(a , FUN = function(X) glm(X))

2 个答案:

答案 0 :(得分:4)

您的paste在此无效。把它拿出来。此外,这里也不需要使用字符串。把它们留下来。您的参数系列也是如此:这些是函数,无需引用它们。

这已经大大简化了代码的长度和概念。现在我们有了这个:

models = list(Sepal.Length ~ Sepal.Width, Sepal.Width ~ Sepal.Length)
families = c(gaussian, Gamma)

我们可以申请:

lapply(models,
       function (model) lapply(families,
                               function (family) glm(model, family, iris)))

...这是一个嵌套的应用程序。缩进暗示了什么属于一起。由于这有点奇怪,我们也可以使用不同参数的笛卡尔积:

params = as.data.frame(t(expand.grid(models, families)))

lapply(params, function (p) glm(formula = p[[1]], data = iris, family = p[[2]]))

第一行在这里有点模糊。 expand.grid允许我们创建所有参数组合的数据框。这是一个例子:

> expand.grid(1 : 3, c('a', 'b'))

  Var1 Var2
1    1    a
2    2    a
3    3    a
4    1    b
5    2    b
6    3    b

不幸的是,lapply使用的数据框方向错误,因为它适用于列。因此,我们t会对其进行调整(并再次将其转换为data.frame,因为t始终会返回matrix。)

这段代码非常有用,因为它使得通过lapply编写嵌套循环更具可读性;不幸的是,它本身是非常难以理解的,所以我们坚持它的功能:

combine_parameters = function (...)
    as.data.frame(t(expand.grid(...)))

这使我们能够编写优雅,可读的代码:

models = list(Sepal.Length ~ Sepal.Width, Sepal.Width ~ Sepal.Length)
families = c(gaussian, Gamma)
params = combine_parameters(models, families)
lapply(params, function (p) glm(formula = p[[1]], family = p[[2]]), data = iris)

答案 1 :(得分:1)

使用lapply:

lapply(c("gaussian", "Gamma"), function(myFamily){
  lapply(c("Sepal.Length ~  Sepal.Width" , 
           "Sepal.Width ~ Sepal.Length"), function(myFormula){
             glm(formula = myFormula, family = myFamily, data = iris)
           })
})

修改 正如@KonradRudolph回答中提到的,我们可以将公式作为带有link =参数的列表传递,例如:

lapply(list(gaussian(link = "identity"), Gamma), function(myFamily){
  lapply(c("Sepal.Length ~  Sepal.Width" , 
           "Sepal.Width ~ Sepal.Length"), function(myFormula){
             glm(formula = myFormula, family = myFamily, data = iris)
           })
})