【问题标题】:How do I pass a formula to lm() without error? [duplicate]如何将公式传递给 lm() 而不会出错? [复制]
【发布时间】:2020-11-11 22:34:30
【问题描述】:

我尝试将公式传递给 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. 

有谁知道问题出在哪里?

【问题讨论】:

  • 只试formula()
  • 我们需要一个示例,因为您的代码应该可以工作,即尝试dependent_var = "y" ; var_names = c("x1", "x2") ps 还有?reformulate ...我猜您有多个因变量?即dependent_var = c("y", "z")
  • 检查 paste0(dependent_var, "~", paste0(var_names, collapse = "+")) 并查看为什么警告消息说它的长度 > 1。
  • @Duck 不幸的是,公式()不起作用。
  • @ Rui Barradas 我在检查 paste0(dependent_var, "~", paste0(var_names, collapse = "+")): "PC_1_mets_men~PC_1_food_men+covar_prev_diab" "PC_2_mets_men~ PC_1_food_men+covar_prev_diab" "PC_3_mets_men~PC_1_food_men+covar_prev_diab"..... 但是,完整的语法与 as.formula() 会抛出错误

标签: r formula lm


【解决方案1】:

有一个警告(不是错误),因为在问题中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

【讨论】:

    【解决方案2】:

    您有一个因变量向量,因此在您的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 日创建

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 2019-09-17
      • 1970-01-01
      • 2020-03-04
      • 2021-02-05
      • 2021-04-16
      • 1970-01-01
      相关资源
      最近更新 更多