繁体   English   中英

在R中使用lapply从函数调用中的向量返回实际函数参数

[英]Returning actual function argument from vector in function call with lapply in R

请考虑以下事项。

我想使用lapply()随后将存储在字符向量中的几个函数参数应用于其他函数。 一个最小的可重现示例可能是将两个或多个“族”应用于glm()函数。 请注意,该示例对于应用此类族可能毫无意义,仅用于说明目的。

以下内容取自?glm()中的示例

counts <- c(18,17,15,20,10,20,25,13,12)
outcome <- gl(3,1,9)
treatment <- gl(3,3)
data.frame(treatment, outcome, counts) # showing data

我们现在可以运行带有家族“高斯”或“泊松”的 GLM

glm(counts ~ outcome + treatment, family = "gaussian")
glm(counts ~ outcome + treatment, family = "poisson")

这也可以通过创建具有这些姓氏的字符向量来“自动化”:

families <- c("poisson", "gaussian")

并在lapply()函数中使用它。

但是一旦运行,返回的函数调用不再返回姓氏,而是返回匿名函数参数x

lapply(families, function(x) glm(counts ~ outcome + treatment, family = x))
#> [[1]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = x)
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   3.045e+00   -4.543e-01   -2.930e-01   -3.242e-16   -2.148e-16  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       10.58 
#> Residual Deviance: 5.129     AIC: 56.76
#> 
#> [[2]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = x)
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   2.100e+01   -7.667e+00   -5.333e+00    2.221e-15    2.971e-15  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       176 
#> Residual Deviance: 83.33     AIC: 57.57

问题:如何在lapply()之后的函数调用中保留/显示来自向量families的家族名称?


期望的结果:结果应该是这样的:

#> [[1]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = "gaussian")
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   3.045e+00   -4.543e-01   -2.930e-01   -3.242e-16   -2.148e-16  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       10.58 
#> Residual Deviance: 5.129     AIC: 56.76
#> 
#> [[2]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = "poisson")
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   2.100e+01   -7.667e+00   -5.333e+00    2.221e-15    2.971e-15  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       176 
#> Residual Deviance: 83.33     AIC: 57.57

我按照这里的建议尝试eval(bquote(x))R: Passing named function arguments from vector ,但这不起作用。 看:

lapply(families, function(x) glm(counts ~ outcome + treatment, family = eval(bquote(x))))
#> [[1]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = eval(bquote(x)))
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   3.045e+00   -4.543e-01   -2.930e-01   -3.242e-16   -2.148e-16  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       10.58 
#> Residual Deviance: 5.129     AIC: 56.76
#> 
#> [[2]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = eval(bquote(x)))
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   2.100e+01   -7.667e+00   -5.333e+00    2.221e-15    2.971e-15  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       176 
#> Residual Deviance: 83.33     AIC: 57.57

reprex 包于 2022-07-22 创建 (v2.0.1)

谢谢!

一种方法是提取族名并将其添加到每个模型对象内的公式中。 例如像这样:

lapply(families, \(fam) { model <- glm(counts ~ outcome + treatment, family = fam); model$call[3] <- model$family$family; return(model)})

输出:

[[1]]

Call:  glm(formula = counts ~ outcome + treatment, family = "poisson")

Coefficients:
(Intercept)     outcome2     outcome3   treatment2   treatment3  
  3.045e+00   -4.543e-01   -2.930e-01   -3.242e-16   -2.148e-16  

Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
Null Deviance:      10.58 
Residual Deviance: 5.129    AIC: 56.76

[[2]]

Call:  glm(formula = counts ~ outcome + treatment, family = "gaussian")

Coefficients:
(Intercept)     outcome2     outcome3   treatment2   treatment3  
  2.100e+01   -7.667e+00   -5.333e+00    2.221e-15    2.971e-15  

Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
Null Deviance:      176 
Residual Deviance: 83.33    AIC: 57.57

根据目的,您还可以(仅)命名向量中的元素,并且每个列表元素都有其名称。

families <- c(poisson = "poisson", gaussian = "gaussian")
lapply(families, function(x) glm(counts ~ outcome + treatment, family = x))

输出:

$poisson

Call:  glm(formula = counts ~ outcome + treatment, family = x)

Coefficients:
(Intercept)     outcome2     outcome3   treatment2   treatment3  
  3.045e+00   -4.543e-01   -2.930e-01   -3.242e-16   -2.148e-16  

Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
Null Deviance:      10.58 
Residual Deviance: 5.129    AIC: 56.76

$gaussian

Call:  glm(formula = counts ~ outcome + treatment, family = x)

Coefficients:
(Intercept)     outcome2     outcome3   treatment2   treatment3  
  2.100e+01   -7.667e+00   -5.333e+00    2.221e-15    2.971e-15  

Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
Null Deviance:      176 
Residual Deviance: 83.33    AIC: 57.57

使用方法 1 更新。

更直接的方法是直接在lapply内部构建和评估调用

lapply(families, function(x) {
  eval(as.call(list(quote(glm), 
               formula = counts ~ outcome + treatment, 
               data = quote(df), 
               family = x)))
  })
#> [[1]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = "poisson", 
#>     data = df)
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   3.045e+00   -4.543e-01   -2.930e-01    1.338e-15    1.421e-15  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       10.58 
#> Residual Deviance: 5.129     AIC: 56.76
#> 
#> [[2]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = "gaussian", 
#>     data = df)
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   2.100e+01   -7.667e+00   -5.333e+00    2.056e-16    7.252e-16  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       176 
#> Residual Deviance: 83.33     AIC: 57.57

reprex 包于 2022-07-22 创建 (v2.0.1)

另一个可能的解决方案:

families <- c("gaussian", "poisson") 
lapply(families, \(x) eval(parse(text=paste0("glm(counts ~ outcome + treatment, 
  df, family = ", x, ")"))))

#> [[1]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = gaussian, 
#>     data = df)
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   2.100e+01   -7.667e+00   -5.333e+00    8.729e-16    7.252e-16  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       176 
#> Residual Deviance: 83.33     AIC: 57.57
#> 
#> [[2]]
#> 
#> Call:  glm(formula = counts ~ outcome + treatment, family = poisson, 
#>     data = df)
#> 
#> Coefficients:
#> (Intercept)     outcome2     outcome3   treatment2   treatment3  
#>   3.045e+00   -4.543e-01   -2.930e-01    1.011e-15    7.105e-16  
#> 
#> Degrees of Freedom: 8 Total (i.e. Null);  4 Residual
#> Null Deviance:       10.58 
#> Residual Deviance: 5.129     AIC: 56.76

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM