[英]Returning actual function argument from vector in function call with lapply in R
Please consider the following.请考虑以下事项。
I want to use lapply()
to subsequently apply several function arguments stored in a character vector to some other function.我想使用
lapply()
随后将存储在字符向量中的几个函数参数应用于其他函数。 A minimal reproducible example could be to apply two or more "families" to the glm()
function.一个最小的可重现示例可能是将两个或多个“族”应用于
glm()
函数。 Please note that the example might be nonsensical for applying such families and is used for illustration purposes only.请注意,该示例对于应用此类族可能毫无意义,仅用于说明目的。
The following is taken from the example in ?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
We can now run a GLM with family "gaussian" or "poisson"我们现在可以运行带有家族“高斯”或“泊松”的 GLM
glm(counts ~ outcome + treatment, family = "gaussian")
glm(counts ~ outcome + treatment, family = "poisson")
This could also be "automated" by creating a character vector with these family names:这也可以通过创建具有这些姓氏的字符向量来“自动化”:
families <- c("poisson", "gaussian")
And using this in an lapply()
function.并在
lapply()
函数中使用它。
But once this runs, the returned function call does not return the family names anymore but the anonymous function argument x
.但是一旦运行,返回的函数调用不再返回姓氏,而是返回匿名函数参数
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
Question: How can the family names from the vector families
be preserved/shown in the function call after lapply()
?问题:如何在
lapply()
之后的函数调用中保留/显示来自向量families
的家族名称?
Desired outcome: The outcome should look like this:期望的结果:结果应该是这样的:
#> [[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
I tried eval(bquote(x))
as suggested here: R: Passing named function arguments from vector , but this did not work.我按照这里的建议尝试
eval(bquote(x))
: R: Passing named function arguments from vector ,但这不起作用。 See:看:
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
Created on 2022-07-22 by the reprex package (v2.0.1)由reprex 包于 2022-07-22 创建 (v2.0.1)
Thank you!谢谢!
An approach could be to extract the family name and add it to the formula within each model object.一种方法是提取族名并将其添加到每个模型对象内的公式中。 For instance like this:
例如像这样:
lapply(families, \(fam) { model <- glm(counts ~ outcome + treatment, family = fam); model$call[3] <- model$family$family; return(model)})
Output:输出:
[[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
Depending on the purpose, you could also (just) name your elements in your vector and each list element would have its name.根据目的,您还可以(仅)命名向量中的元素,并且每个列表元素都有其名称。
families <- c(poisson = "poisson", gaussian = "gaussian")
lapply(families, function(x) glm(counts ~ outcome + treatment, family = x))
Output:输出:
$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
Update with approach 1.使用方法 1 更新。
A more direct way to do this would be to build and evaluate the call directly inside lapply
更直接的方法是直接在
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
Created on 2022-07-22 by the reprex package (v2.0.1)由reprex 包于 2022-07-22 创建 (v2.0.1)
Yet another possible solution:另一个可能的解决方案:
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.