如何将公式无误地传递给 lm()?

How do I pass a formula to lm() without error?

我尝试将公式传递给 lm()。但是,当我执行以下操作时:

independend_vars <- c("PC_1_food_men","covar_prev_diab")
dependent_var <- c("PC_1_mets_men", "PC_2_mets_men", "PC_3_mets_men")

var_names <- independend_vars

formula <- as.formula(paste0(dependent_var, "~", paste0(var_names, collapse = "+")))

我收到以下错误:

Warning:
Using formula(x) is deprecated when x is a character vector of length > 1.
  Consider formula(paste(x, collapse = " ")) instead. 

有人知道问题出在哪里吗?

你有一个因变量向量,所以你在 paste 调用后有一个公式向量。您一次只能传递一个给 as.formula:

independend_vars <- c("PC_1_food_men","covar_prev_diab")
dependent_var <- c("PC_1_mets_men", "PC_2_mets_men", "PC_3_mets_men")

var_names <- independend_vars
string_form <- paste0(dependent_var, "~", paste0(var_names, collapse = "+"))

string_form
#> [1] "PC_1_mets_men~PC_1_food_men+covar_prev_diab"
#> [2] "PC_2_mets_men~PC_1_food_men+covar_prev_diab"
#> [3] "PC_3_mets_men~PC_1_food_men+covar_prev_diab"

as.formula(string_form)
#> Warning: Using formula(x) is deprecated when x is a character vector of length > 1.
#>   Consider formula(paste(x, collapse = " ")) instead.
#> PC_1_mets_men ~ PC_1_food_men + covar_prev_diab

如果您想要 3 个不同的公式,可以在 lapply

中执行 as.formula
lapply(string_form, as.formula)
#> [[1]]
#> PC_1_mets_men ~ PC_1_food_men + covar_prev_diab
#> <environment: 0x0000000015620b28>
#> 
#> [[2]]
#> PC_2_mets_men ~ PC_1_food_men + covar_prev_diab
#> <environment: 0x0000000015620b28>
#> 
#> [[3]]
#> PC_3_mets_men ~ PC_1_food_men + covar_prev_diab
#> <environment: 0x0000000015620b28>

如果您不想要 3 个公式,我不清楚您要做什么。

reprex package (v0.3.0)

于 2020 年 7 月 22 日创建

出现警告(不是错误),因为在问题 dependent_var 中有多个元素,它让您知道它忽略了除第一个元素之外的所有元素。另请注意,您不必将字符串转换为公式,因为 lm 将接受一个字符串,但如果给定一个长度 > 1 的字符向量,它将忽略除第一个元素以外的所有元素并给出类似的警告。

我们可以把问题中的代码修改成这样:

paste(sprintf("cbind(%s)", toString(dependent_var)), "~", 
  paste(var_names, collapse = " + "))

给予:

[1] "cbind(PC_1_mets_men, PC_2_mets_men, PC_3_mets_men) ~ PC_1_food_men + covar_prev_diab"

但是,在下一节中使用 reformulate 会更容易一些。

重新制定

相反,我们可以使用 sprintf 形成 LHS,然后将其与 reformulate 中的自变量一起使用。使用内置的 CO2 数据集,我们实际上可以 运行 结果:

dep_vars <- names(CO2)[4:5]    # c("conc", "uptake")
indep_vars <- names(CO2)[2:3]  # c("Type", "Treatment")

fo <- reformulate(indep_vars, sprintf("cbind(%s)", toString(dep_vars)))
fo
## cbind(conc, uptake) ~ Type + Treatment

lm(fo, CO2)

给予:

Call:
lm(formula = fo, data = CO2)

Coefficients:
                  conc        uptake    
(Intercept)        4.350e+02   3.697e+01
TypeMississippi   -5.582e-14  -1.266e+01
Treatmentchilled   0.000e+00  -6.860e+00

这个问题有多个因变量,但如果只有一个因变量,那么我们可以简化重新表述的语句。例如,只使用第一个因变量:

reformulate(indep_vars, dep_vars[1])
## conc ~ Type + Treatment

更好看的电话线

上面的 Call: 行显示 RHS 字面意思 fo 但我们可以使用 do.call 强制它产生更好看的 Call: 行。

do.call("lm", list(fo, quote(CO2)))

给予:

Call:
lm(formula = cbind(conc, uptake) ~ Type + Treatment, data = CO2)

Coefficients:
                  conc        uptake    
(Intercept)        4.350e+02   3.697e+01
TypeMississippi   -5.582e-14  -1.266e+01
Treatmentchilled   0.000e+00  -6.860e+00